2016-05-16 166 views
0

我需要对在套接字程序中使用多个发送/接收进行说明。 我的客户端程序如下所示(使用TCP SOCK_STREAM)。在套接字中发送多个发送/接收

send(sockfd,"Messgfromlient",15,0); 
    send(sockfd,"cli1",5,0); 
    send(sockfd,"cli2",5,0); 
    send(sockfd,"cli3",5,0); 
    send(sockfd,"cli4",5,0); 
    send(sockfd,"cli5",5,0); 

和服务器程序如下所示。

recv(newsockfd,buf,20,0); 
    printf("Buffer is %s\n",buf); 

当我执行上述程序,则输出为如下:

客户端消息:Messgfromlient

相信BUF大小为20,因此,只有一个缓冲器得到接收。 在服务器端添加一个recv。

char buf[20],buf[20]; 
    ------skipped------ 
    recv(newsockfd,buf,20,0); 
    recv(newsockfd,buf1,20,0); 
    printf("Client Msg :%s\n",buf); 
    printf("Client Msg :%s \n",buf1); 

输出: 第一次试验:

Client Msg :Messgfromlient 
    Client Msg :cli2 

第二个线索:

Client Msg :Messgfromlient 
    Client Msg :cli1 

正如我们可以看到,有在。OUPUTS一些矛盾, 从客户端看起来一切邮件正在发送,但在服务器中,msg将基于buf大小接收,这里尽管buf1的大小为20,为什么'cli3''cli4''cli4'msgs没有在bu上收到F1?有没有特定的限制?请澄清一下。

由于事先 拉贾

+1

send()和recv()是什么返回值?你不能忽视这一点。 –

+0

您正在发送5个字节和15个字节的缓冲区,但在接收时,您正在打印以第一个“NUL”字节(0x00)结尾的字符串。如果你保存了'recv()'调用的返回值并打印它们,这可能会有所帮助。 – TripeHound

+1

传递的'len'是允许的最大长度。 'recv'可以返回一个字符或者(在非阻塞系统中)a -'1'。您的“问题”属于进程调度:它取决于在上下文切换之前执行的代码点以及内核已经分离的内容。 – LPs

回答

3

TCP是一个字节流的协议,因此它不知道的消息。您总共发送25字节,而另一方的每个recv将读取这些字节的一些。你可以得到20,你可能会得到1然后19在接下来的阅读,你可能会得到5然后4然后11然后5.大小参数recv是最大读取的数量。

您需要进行循环,直到您自己阅读完整消息,并且也明白您可能会在同一收到的消息中收到多个“发送”消息。

3

服务器程序看起来像下面。

recv(newsockfd,buf,20,0); 
printf("Buffer is %s\n",buf); 

这已经是错误的。它应该是:

int count = recv(newsockfd,buf,20,0); 
if (count == -1) 
{ 
    perror("recv"); // please improve this message 
    close(newsocketfd); 
} 
else if (count == 0) 
{ 
    // peer has closed the connection 
    close(newsockfd); 
} 
else 
{ 
    printf("Buffer is %.*s\n",count,buf); 
} 

这应该给你足够的暗示的......

2

你有2个问题:

当你显示结果,你要停在第一个空字节,它始终是“Messgfromlient”之后。可能有更多的文字已经收到,但你没有显示它。

第二个问题是TCP连接是一个流。您可能一次接收所有数据,您可能只收到第一个字节。你不知道哪一个是它,也不能预测它。您需要处理应用程序中的不完整读取,并且必须处理重试。

但是,您可以更有可能将所有数据发送到一个数据包而不是6个。查看TCP_CORK选项。