简体   繁体   中英

Java client only receives first response from C server

I am creating a simple game which consists of Java client and C server. 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. I am pretty desperate and I tryied variety of actions and changed the message from server like 1000 times but nothing works.

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:

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. so my code looks like this out.write(message + "\\n"); and then just call flush() and it will be ok.

You have to add the enline character, but if you had use the printWriter instead then you could use the println method...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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