[英]Reading c socket from java hangs/blocks
我在Java和C之间的套接字有问题。我有一个C程序,它创建一个套接字并开始监听。 Java客户端可以正常工作,并且在某些情况下会打开套接字并对其进行写入,然后尝试从中读取,但是这会阻塞。
这是C程序的套接字部分:
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
char wbuffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
cout << "ERROR opening socket" << endl;
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 23456;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
int on = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
cout << "Couldn't set socket params!" << endl;
int so = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
while(so < 0) {
cout << "ERROR on binding" << endl;
sleep(1);
so = bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
cout << "ERROR on accept" << endl;
bzero(buffer,256);
//cout << "Socket created!" << endl;
n = read(newsockfd,buffer,255);
if (n < 0)
cout << "Error reading from socket" << endl;
if (strcmp(buffer, "power\n") == 0) {
// Do stuff
strcpy(wbuffer, "off\n");
}
//sleep(1);
n = write(newsockfd,wbuffer,strlen(wbuffer));
if (n < 0)
cout << "ERROR writing to socket" << endl;
}
//cout << "message: " << buffer << endl;
close(newsockfd);
close(sockfd);
而Java方面:
Socket socket3 = new Socket("localhost", 23456);
PrintWriter out3 = new PrintWriter(socket3.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket3.getInputStream()));
out3.write("power" + "\n");
//String status = in.readLine();
log.debug("Wrote power");
StringBuffer buffer = new StringBuffer();
while (true) {
int ch = in.read();
log.debug("in.read()");
if ((ch < 0) || (ch == '\n')) {
break;
}
buffer.append((char) ch);
}
String status = buffer.toString();
out3.close();
in.close();
socket3.close();
写作工作已经完成,我已经进行了一些调试,最后要做的就是阅读,尤其是in.read()。
我可能在Java方面缺少一些东西,因为C测试客户端很好地读取了输出。
希望有人对如何使它起作用有想法,我愿意接受任何解决方案。
您的C ++代码非常可怕。 考虑一下read(2)
返回小于6
情况会发生什么。 一般而言:
n = read(newsockfd,buffer,255);
if (n < 0)
cout << "Error reading from socket" << endl;
// continuing processing after an error - BAD
// not paying attention to n - BAD
if (strcmp(buffer, "power\n") == 0) {
// Do stuff
strcpy(wbuffer, "off\n");
}
// potentially writing zero bytes here - BAD
n = write(newsockfd,wbuffer,strlen(wbuffer));
if (n < 0)
cout << "ERROR writing to socket" << endl;
} // WHERE DID THIS PAREN COME FROM?
因此,请解决这些问题。 使用tcpdump(1)
或wireshark检查您在网络上得到了什么。 双面打印您的输入。 您可能会发现您的假设不在某个地方。
原来,问题实际上不在阅读部分,而是在写作方面。 我忘了刷新输出,所以它实际上并没有开始读取,或者有什么要读取的。 添加冲洗后,读取效果很好,我什至可以使用readline()简化代码。
在其他情况下,我只写给套接字的方法起作用,因为在关闭流时调用了flush,这使我失望了。
C代码令人讨厌,我需要清理它并实际处理异常。
无论如何,感谢大家为我提供的帮助,如果没有答案,发现我的错误将花费更长的时间。
也许问题在于您正在读取Integer:
int ch = in.read()
您是否尝试过将其更改为:
char ch = in.read()
或者在比较之前将整数转换为char:
if((char) ch == '\n' || ch < 0)
我现在想不出什么...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.