0

我正在尝试创建一个简单的套接字连接。

这就是我的客户正在做的事情:

strcpy(send_data, "Hello Server");
send(sock,send_data,strlen(send_data), 0);

strcpy(send_data, "Compression Method:  null(0)");                      
send(sock,send_data,strlen(send_data), 0);

strcpy(send_data, "end");                      
send(sock,send_data,strlen(send_data), 0);

send_data定义为char send_data[1024]

现在这是我的服务器端:

    int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrLen);

    while(clntSock){

        int inMsgLen = recvfrom(clntSock, inMsg, 1024, 0,(struct sockaddr *)&clntAddr, (socklen_t*)&clntAddrLen);

        inMsg[inMsgLen] = '\0';

        if(strcmp(inMsg, "Hello Server") == 0){   // check if the client sent hello server

            printf("%s\n", inMsg);

        } else if(strcmp(inMsg, "end") == 0){  // check if client send end

            printf("\n WHY ISNT"T THIS EXECUTING\n"); // THIS IS NOT HAPPENING

        } else {

            printf("%s\n", inMsg);  //keep receiving and do nothing
        }

现在我的服务器设法进行第一次检查(即检查客户端是否向服务器发送了问候)并打印出:Hello Server

然后它转到 else 语句并打印出:Compression Method: null(0)

之后它继续进入 else 语句......它永远不会执行 else if 语句

*为什么 else_if 语句永远不会被执行?*

4

3 回答 3

3

您假设对等方的一次发送等于一次接收。不是这样的。TCP 是一种字节流协议。如果你想要消息,你必须自己安排它们,例如,行,长度-字前缀,类型-长度-值,XML,...

于 2013-09-23T10:37:53.090 回答
1

在 TCP 层上,您需要实现某种协议。这意味着您的客户端应该发送一些指示符,即它将要发送的字符串的固定大小长度,然后是实际字符串(对于简单的协议)。在您的服务器代码中,您不能只接收并期望字符串完全到达。它可以被切成几块,所以你可以这样做:

 1. Client sends a fixed length header (for example. N chars which have the length of the following string)
 2. Since the server knows now that the the header has a fixed length, it should wait until this header has arrived.
 3. Parse the header to see how many data the client wants to send and then loop as long as a full message has not yet been delivered.

对于更复杂的情况,您可能需要一个协议,该协议还允许在客户端发送错误数据的情况下重新同步,但您必须根据这对您的重要性来决定。对于简单的客户端/服务器,应该使用上述方案。我正在使用相同的方法。

于 2013-09-23T11:16:22.973 回答
0

在客户端,您正在这样做:

Send ("Hello Server");

Send("Compression Method: null(0)");

Send("end");

所以,在你的套接字流中,你有这个:

Hello ServerCompression Method: null(0)end

当您在服务器上发出 Recv(1024) 时,它可能会从 1 个单个字符返回到整个字符串,这意味着您可能会收到任何组合。这就是为什么您需要告诉服务器您在每个 send() 中发送了多少个字符。此外,您可以使用 \n 或 \0 等特殊字符结束每个字符串,以便您可以在服务器端分隔字符串。这不是很推荐,因为字符串本身可能包含该特殊字符。

如果要发送和接收单个数据包,请考虑使用 UDP 而不是 TCP。使用 UDP,服务器在客户端发送数据包时接收数据包。在转向 UDP 之前,请在此处阅读并了解 UDP 与 TCP 的优缺点

于 2013-09-23T11:19:55.307 回答