简体   繁体   English

Java 客户端只接收来自 C 服务器的第一个响应

[英]Java client only receives first response from C server

I am creating a simple game which consists of Java client and C server.我正在创建一个由 Java 客户端和 C 服务器组成的简单游戏。 When client sends first request to server, it is ok.当客户端向服务器发送第一个请求时,就可以了。 The server sends response and client reads it.服务器发送响应,客户端读取它。 But when client send second request, the server sends response like always but client reads nothing.但是当客户端发送第二个请求时,服务器像往常一样发送响应,但客户端什么也没读。 When I delete \\n from response, clinet is stuck on readLine() which is ok, but when I place \\n back, readLine() reads nothing.当我从响应中删除 \\n 时,clinet 卡在 readLine() 上,这没问题,但是当我放回 \\n 时, readLine() 什么也没读。 I am pretty desperate and I tryied variety of actions and changed the message from server like 1000 times but nothing works.我非常绝望,我尝试了各种操作,并更改了来自服务器的消息 1000 次,但没有任何效果。

Here is connection method:下面是连接方法:

public int connect() {
    try {
        if (port != 0 && !host.equals(null)) {
            socket = new Socket(host, port);
            socket.setSoTimeout(5000);
            socket.setKeepAlive(true);
        } else {
            socket = new Socket("localhost", 50001);
        }

        out = new OutputStreamWriter(socket.getOutputStream());
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    } catch (UnknownHostException ex1) {
        System.out.println("Unknown host: " + host);
        return 1;
    } catch (IOException ex2) {
        System.out.println("No I/O: " + ex2.getMessage());
        return 2;
    }
    return 0;
}

Here are methods for comunication:以下是沟通的方法:

public String listRooms() throws DisconnectedException, IOException {
    this.send(LIST_ROOMS);

    String data = this.receive();
    System.out.println("Action: " + LIST_ROOMS + " Result: " + data);

    return data;        
}

public int createRoom(String playerName) throws IOException, DisconnectedException {
    this.send(playerName, CREATE_ROOM);

    int result = this.receiveInt();
    System.out.println("Action: " + CREATE_ROOM + " Result: " + result);
    return result;
}

public void joinRoom(String playerName, int number) throws IOException, DisconnectedException {

    String message = number + "\0" + playerName;

    this.send(message, JOIN_ROOM);

    try {
        System.out.println("Action: " + JOIN_ROOM + " Result: " + this.receive());
    } catch (SocketTimeoutException e) {
        throw new DisconnectedException("Connection with server lost...");
    }
}

private void send(String message, int actionNumber) throws IOException {
    out.write((char) actionNumber);
    out.write(message);
    out.flush();
}

private void send(int actionNumber) throws IOException {
    out.write((char) actionNumber);
    out.flush();
}

private int receiveInt() throws IOException {
    int response = in.read();
    System.out.println(response);


    return 0;
}

private String receive() throws IOException {
    String answer = in.readLine();

    System.out.println("ANSWER: " + answer);        

    if (answer == null) {
        System.out.println("You recieved nothing Jon Snow...");
    } else if ("0".equals(answer)) {
        System.out.println("Error recieveing answer from server");
        return "0";
    }

    return answer;
}

and here is server:这是服务器:

#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

#include "room.h"

void error_message(const char *msg);

typedef struct thread_args
{
    int client_sock;
    char ip_address[16];
} thread_args;


void *thread_service(void *args)
{
    int client_sock;
    char buffer[256] = "";
    char cbuf;
    int n;
    char address[16] = "";
    int result = 0;
    room *room = NULL;


    client_sock = ((thread_args *) args)->client_sock;
    strcpy(address, ((thread_args *) args)->ip_address);

    pthread_detach(pthread_self());

    while(1)
    {
        if ((recv(client_sock, &cbuf, 1, 0)) == -1)
        {
            printf("Receive message from %s failure\n", address);
            break;
        }

        switch (cbuf) {
            case 0:
                result = create_room(&room, client_sock);

                if(!result)
                {
                    /* TODO */
                }
                memset(buffer, 0, 256);
                sprintf(buffer, "%d\n", result);

                n = send(client_sock, buffer, 256, 0);

                if (n <= 0) {
                  perror("ERROR writing to socket\n");
                  close(client_sock);
                  break;
                }
                printf("sent\n");
                break;
            case 1:
                result = join_room(&room, client_sock);
                if(!result)
                {
                    /* TODO */
                }

                printf("Join to room for %s\n", address);
                sprintf(buffer, "%d\n", result);
                n = send(client_sock, buffer, 256, 0);

                if (n <= 0) {
                  perror("ERROR writing to socket\n");
                  break;
                }

                break;
            case 2:
                printf("List rooms\n");
                memset(buffer, 0, 256);
                result = list_rooms(buffer);

                if(!result) {
                    /* TODO */
                }

                printf("Sending message: %s", buffer);
                n = send(client_sock, buffer, 256, 0);

                if (n <= 0) {
                  perror("ERROR writing to socket\n");
                  close(client_sock);
                  break;
                }
                printf("Sent\n");
                break;
            case 5:
                exit(0);
                break;
        }

    }
    close(client_sock);
    free(args);
    return 0;
}

int main(int argc, char *argv[])
{
int sock_fd = 0, new_sock_fd = 0, port = 0, clilen = 0;
struct sockaddr_in serv_addr, cli_addr;
int *th_socket;
pthread_t thread_id;
thread_args *args = (thread_args *)malloc(sizeof(thread_args));
char address[16];
int yes = 1;

if(argc < 2)
{
    fprintf(stderr, "Error missing port");
    return 0;
}

sock_fd = socket(AF_INET, SOCK_STREAM, 0);

if(sock_fd < 0)
    fprintf(stderr, "Error opening socket");

memset(&serv_addr, 0, sizeof(serv_addr));

port = atoi(argv[1]);

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = INADDR_ANY;

if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == 0)
{
    printf("Socket options was set.\n"); //TODO
}
else
{
    printf("Set socket options failure.\n"); //TODO
}

if(bind(sock_fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    error_message("Error in connection");

listen(sock_fd, 5);

if (pthread_mutex_init(&lock, NULL) != 0)
{
    printf("Mutex init failed.\n");
    return 1;
}

while(1)
{
    printf("Waiting for new connection\n");
    clilen = sizeof(cli_addr);
    new_sock_fd = accept(sock_fd, (struct sockaddr *)&cli_addr, &clilen);

    if (new_sock_fd < 0) {
        printf("Error accepting new connection!\n");
        continue;
    }

    strcpy(args->ip_address, inet_ntoa(cli_addr.sin_addr));
    args->client_sock = new_sock_fd;

    if (new_sock_fd > 0 ) {
        th_socket=malloc(sizeof(int));
        *th_socket=new_sock_fd;

        printf("Creating new thread for %s\n", args->ip_address);
        pthread_create(&thread_id, NULL, (void *)&thread_service, (void *)args);
    } else {
        printf("Error creating thread for new connection.\n");
        return -1;
    }
}

return 0;
}

So if you want to send C servera message, it will look like this:所以如果你想发送 C servera 消息,它看起来像这样:

String message = "Hello world!";

OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
out.write(message + "\n");
out.flush();

UPDATE : A have figured that out, it was pretty nasty fault, maybe it would help others.. In message from JAVA client to server must be (in my case) manually appended "\\n" character, otherwise it sends some characters that will confuse the server.更新:A 已经发现,这是一个非常讨厌的错误,也许它会帮助其他人.. 在从 JAVA 客户端到服务器的消息中必须(在我的情况下)手动附加“\\n”字符,否则它会发送一些字符混淆服务器。 so my code looks like this out.write(message + "\\n");所以我的代码看起来像这样out.write(message + "\\n"); and then just call flush() and it will be ok.然后调用flush()就可以了。

You have to add the enline character, but if you had use the printWriter instead then you could use the println method...您必须添加 enline 字符,但是如果您使用了 printWriter,那么您可以使用println方法...

PrintWriter pw =  new PrintWriter(socket.getOutputStream(), true);
pw.println("Bla bla");

So the answer is simple.所以答案很简单。 If you are using OutputStreamWritter you have to add newline character to your message.如果您使用的是 OutputStreamWritter,则必须在消息中添加换行符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM