Java客户端仅从C服务器

时间:2017-01-11 15:43:48

标签: java c

我正在创建一个由Java客户端和C服务器组成的简单游戏。当客户端向服务器发送第一个请求时,没关系。服务器发送响应,客户端读取它。但是当客户端发送第二个请求时,服务器会像往常一样发送响应,但客户端什当我从响应中删除\ n时,clinet卡在readLine()上就可以了,但是当我放回\ n时,readLine()什么都不读。我非常绝望,我尝试了各种各样的操作,并将服务器中的消息改为1000次,但没有任何作用。

这是连接方法:

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;
}

以下是通信方法:

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;
}

这是服务器:

#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;
}

因此,如果您想发送C servera消息,它将如下所示:

String message = "Hello world!";

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

更新:A已经弄清楚了,这是非常讨厌的错误,也许它会帮助别人..在从JAVA客户端到服务器的消息必须(在我的情况下)手动附加“\ n “字符,否则它会发送一些会混淆服务器的字符。所以我的代码看起来像这个out.write(message + "\n");,然后只需调用flush()就可以了。

2 个答案:

答案 0 :(得分:1)

您必须添加内联角色,但如果您使用了printWriter,那么您可以使用 println 方法......

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

答案 1 :(得分:0)

所以答案很简单。如果您正在使用OutputStreamWritter,则必须在邮件中添加换行符。