通过socket从Java发送到C - 奇怪的结果

时间:2013-04-20 07:02:57

标签: java c sockets network-programming

我有一个用Java编写的简单服务器,它只是将一个Integer发送到一个连接的客户端。我有一个用C编写的客户端,它连接到服务器并打印出收到的Integer。

我的问题是结果有所不同。大约一半时间执行客户端我得到正确的结果(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;
}

2 个答案:

答案 0 :(得分:1)

您能确定在客户端收到sizeof intBuffer个字节吗?不,你不能,因为recv()可能会返回更少的字节然后请求。

修改代码以循环recv(),只要接收到的请求字节数更少且没有错误发生。

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

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

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

答案 1 :(得分:-1)

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

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

这意味着Java int - &gt; C longJava short - &gt; C int
现在,这取决于您的优先事项所在。

如果您想在Java中执行激烈的数学计算并将结果通过套接字发送到C,我建议您执行Java int -> C long
如果您只想发送小数字并在C中完成密集计算,请执行Java short - &gt; C int次转化。

希望有所帮助。