发送INT - 奇怪的结果
我用Java编写的一个简单的服务器,只是将一个整数连接的客户端。我有一个用C编写的客户端,它连接到服务器并打印出接收到的Integer。发送INT - 奇怪的结果
我的问题是结果不一样。大约有一半执行客户端我得到正确的结果(234)的时代,但有时我得到8323072.
这是服务器:
class TCPServer {
public static void main(String args[]) throws Exception {
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
System.out.println("welcomeSocket.accept() called");
DataInputStream inFromClient = new DataInputStream(connectionSocket.getInputStream());
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
outToClient.writeInt(234);
}
}
}
这是客户端:
int main(int argc, char *argv[])
{
if(argc != 4){
printUsage();
return;
}
char* serverIP = argv[1];
char* serverPortC = argv[2];
char* integerToSendC = argv[3];
int serverPort = atoi(serverPortC);
int integerToSend = atoi(integerToSendC);
int socketDesc = socket(AF_INET, SOCK_STREAM, 0);
if(socketDesc < 0) {
printf("Error when creating socket\n");
return;
}
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(serverPort);
inet_pton(AF_INET, serverIP, &serverAddr.sin_addr);
int connection = connect(socketDesc, (struct sockaddr*) &serverAddr, sizeof serverAddr);
if(connection < 0) {
printf("Error when establishing connection\n");
return;
}
char intBuffer[4];
if(recv(socketDesc, intBuffer, sizeof intBuffer, 0) == -1){
printf("Error while receiving Integer\n");
}
int receivedInt = ntohl(*((int *) &intBuffer));
printf("Received int: %d\n", receivedInt);
close(socketDesc);
}
在此先感谢您的帮助!
编辑:那么,到底 我做了这样的事情,只是任何人谁具有相同的问题:
while(receivedBytes < 4){
int readBytes = read(receiverSocket, &intBuffer, (sizeof intBuffer) - receivedBytes, receivedBytes);
receivedInteger += (intBuffer << (8*receivedBytes));
receivedBytes += readBytes;
}
你可以确信你已经收到客户端上的sizeof intBuffer
字节?不,您不能,因为recv()
可能会返回较少的字节,然后请求。
国防部您的代码回路周围recv()
只要少字节随后要求已收到,并没有出现错误。
请注意,recv()
ing 0
字节表示连接已被另一端关闭。
还要确保服务器端网络字节顺序发送。
另外^ 2:在初始化变量(intBuffer
这里),至少在开发阶段,会说:优化阶段之前是个好主意。
它不会扩展收到的值:'123'映射到网络上的'00 00 00 7B'。收到的值“8323072”是“7F 00 00 00”。即使读取1个字节,它也不应该是'7F'。 – 2013-04-20 20:22:52
@ValeriAtamaniouk:大多数propably对方挂断连接,'的recv()''与返回0',所以没有错误消息记录和'8323072'被打印出来'receivedInt'是简单地作为垃圾'intBuffer'在传递给'recv()'之前没有初始化。 – alk 2013-04-22 15:14:41
可能是,但是这并不完全匹配相应的部分源:DataOutputStream外壳在关闭之前发送4个字节。 – 2013-04-22 17:16:22
你的问题可能是由于各种数据类型的子边界。
在Java中,4字节分配给int
,2字节分配给short
。
在C中,4字节用于long
和2个字节用于int
。
这意味着Java int
→C long
和Java short
→C int
。
现在这取决于你的优先事项在哪里。
如果要执行Java中的激烈的数学计算和在插座结果发送到C,我建议你做Java int -> C long
或
如果你想只发送少量的数字和在C做了激烈的计算,做Java short
- >C int
转换。
希望有帮助。
在C中,在我的计算机中,4个字节用于'int'。 – johnchen902 2013-04-20 07:11:00
请参见[DataOutputStream.writeInt](http://docs.oracle.com/javase/6/docs/api/java/io/DataOutputStream.html#writeInt(int))。看起来'writeInt'总是以big-endian写入4个字节。只要它在C端作为一个4字节的'int'被正确地重新组装,我就会认为这是正确的。 – WhozCraig 2013-04-20 07:11:43
@WhozCraig我不用C编程。我只是指维基百科上的基本数据类型的大小,它表示C分配* 16位*(2字节)因此我的答案。如果答案中有错误,或者如果首先出错,请告诉我。我将立即删除它,以免混淆OP – 2013-04-20 07:13:57
可能可能是因为多少字节分配'在Java和C及其相关子边界int'。尝试发送小号码。如果Java为int分配4个字节,则C分配2个字节。因此,该范围在C – 2013-04-20 07:04:47
中少得多,该数目是2 ** 16 * 127(即,第三个字节全1,底部的两个全0) – 2013-04-20 07:08:55
@LittleChild我本来也这么认为,但[DataOutputStream.writeInt](http://docs.oracle.com/javase/6/docs/api/java/io /DataOutputStream.html#writeInt(int))似乎很清楚发送四个字节,至少在32位运行时。 – WhozCraig 2013-04-20 07:09:37