2013-04-20 49 views
0

我用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; 
} 
+1

可能可能是因为多少字节分配'在Java和C及其相关子边界int'。尝试发送小号码。如果Java为int分配4个字节,则C分配2个字节。因此,该范围在C – 2013-04-20 07:04:47

+0

中少得多,该数目是2 ** 16 * 127(即,第三个字节全1,底部的两个全0) – 2013-04-20 07:08:55

+0

@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

回答

1

你可以确信你已经收到客户端上的sizeof intBuffer字节?不,您不能,因为recv()可能会返回较少的字节,然后请求。

国防部您的代码回路周围recv()只要少字节随后要求已收到,并没有出现错误。

请注意,recv() ing 0字节表示连接已被另一端关闭。

还要确保服务器端网络字节顺序发送。

另外^ 2:在初始化变量(intBuffer这里),至少在开发阶段,会说:优化阶段之前是个好主意。

+0

它不会扩展收到的值:'123'映射到网络上的'00 00 00 7B'。收到的值“8323072”是“7F 00 00 00”。即使读取1个字节,它也不应该是'7F'。 – 2013-04-20 20:22:52

+0

@ValeriAtamaniouk:大多数propably对方挂断连接,'的recv()''与返回0',所以没有错误消息记录和'8323072'被打印出来'receivedInt'是简单地作为垃圾'intBuffer'在传递给'recv()'之前没有初始化。 – alk 2013-04-22 15:14:41

+0

可能是,但是这并不完全匹配相应的部分源:DataOutputStream外壳在关闭之前发送4个字节。 – 2013-04-22 17:16:22

-1

你的问题可能是由于各种数据类型的子边界。

在Java中,4字节分配给int,2字节分配给short
在C中,4字节用于long和2个字节用于int

这意味着Java intC longJava shortC int
现在这取决于你的优先事项在哪里。

如果要执行Java中的激烈的数学计算和在插座结果发送到C,我建议你做Java int -> C long
如果你想只发送少量的数字和在C做了激烈的计算,做Java short - >C int转换。

希望有帮助。

+1

在C中,在我的计算机中,4个字节用于'int'。 – johnchen902 2013-04-20 07:11:00

+0

请参见[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

+0

@WhozCraig我不用C编程。我只是指维基百科上的基本数据类型的大小,它表示C分配* 16位*(2字节)因此我的答案。如果答案中有错误,或者如果首先出错,请告诉我。我将立即删除它,以免混淆OP – 2013-04-20 07:13:57