在C中,接收/发送您通常做的数据(大致):
服务器:
在客户端:
我的问题来自服务器完成后的 accept
。
想象一下,在服务器端 accept
之后有三条单独的行
发送数据:
connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL);
write(connfd, var1, var1Size);
write(connfd, var2, var2Size);
write(connfd, var3, var3Size);
这是否意味着在客户端我需要三次读取? 像这样:
read(sockfd, &x, size1);
read(sockfd, &y, size2);
read(sockfd, &z, size3);
换句话说,发送和接收呼叫应该如何对应 在服务器端和客户端?每个发送应该是客户端的相应接收吗?
如果在客户端,经过3次读取调用(如上所述)后,我想将数据发送到服务器怎么办? 我可以分别在客户端和服务器端添加一个新发送和一个新接收吗?
所有这些发送/接收是否应在单个accept
呼叫上下文中发生?
这是一张图片,可以更好地说明我可能感兴趣的场景:
欢迎使用伪代码解释如何处理这种连接。
答案 0 :(得分:3)
除非您使用的是具有“消息”概念的协议,例如UDP,你所拥有的只是一个字节流。您可以按照自己的意愿发送和接收它们。
例如,您可以发送两个16位整数并将它们作为一个32位整数接收。这可能不是你想要的,但它完全合法,并且在需要 的情况下一直使用。只要对您的应用程序有意义,您就可以独立地组合数据结构(发送和接收)。您的字节按write()的顺序发送,您将以相同的顺序接收它们。即。
send(var1) ---> recv(var1)
send(var2) ---> recv(var2)
在var2
之前,您将收到var1
正常TCP中的 no 方式(禁止未使用的边缘情况,我甚至都没有指定,因为没有人应该使用它们)
TCP通信是双向的:每个端点(客户端和服务器)可以同时发送。由您和您的应用程序决定何时发送以及何时接收。发送和接收缓冲区是独立的:你可以发送几个字节,接收一些,发送更多......并且它们之间不会有任何干扰(即你不会通过发送一些数据而不是“覆盖”接收缓冲区亦然)。
我将再次重复:TCP中的所有内容都是字节流。 TCP不知道也不关心这些字节是如何构造的,无论是在发送方还是在接收方。它是 ALL 由您决定。发送整数或数据结构时,您将发送内存转储, as bytes 。
例如,在尝试send()
数据结构时会出现一个常见错误,并且由于发送缓冲区已满,系统将进行部分写入。如果您没有检查send()
调用的返回状态以检测这种情况,然后自己发送剩余的字节 ,则在另一个send()
调用中,您的客户端将是如果你指定了MSG_WAITALL,那么当它需要完整的结构并且只接收其中的一部分时,它会被卡在recv()
中。
答案 1 :(得分:0)
TCP是一种流协议,在接收方,您无法确定调用该发送的次数。每当调用recv时,它将给出要读取的字节数,如果请求的字节数不可用,则它将返回当前在套接字缓冲区中的字节数。
如果是UDP,它会像你提到的那样工作,它是一个数据报协议。 (使用recvfrom来恢复数据)