0

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

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

2 回答 2

1

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

recv()只要收到少于请求的字节并且没有发生错误,您的代码就会循环。

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

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

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

于 2013-04-20T09:25:03.590 回答
-1

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

在 Java 中,分配 4 个字节,分配int2 个字节short
在 C 中,4 个字节是 forlong和 2 个字节 for int

这意味着Java int->C longJava short-> C int
现在这取决于您的优先事项在哪里。

如果您想在 Java 中执行密集的数学计算并通过套接字将结果发送到 C,我建议您这样做,Java int -> C long或者
如果您只想发送少量数字并在 C 中完成密集的计算,请执行Java short->C int转换。

希望有帮助。

于 2013-04-20T07:09:52.793 回答