[英]Java client only receives first response from C server
我正在創建一個由 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()就可以了。
您必須添加 enline 字符,但是如果您使用了 printWriter,那么您可以使用println方法...
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
pw.println("Bla bla");
所以答案很簡單。 如果您使用的是 OutputStreamWritter,則必須在消息中添加換行符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.