recv()用于无法工作的较大数据量
我正在用新设计的协议实现一台服务器。按照协议,客户机发送头,后跟数据。标头包含元信息,包括数据大小 我们提供示例客户端,但客户端程序也可以由第三方编写。所以,我们不能完全依赖于报头中提供的数据字段的大小 现在,我面临一个有关recv()用于无法工作的较大数据量,c,sockets,network-programming,recv,C,Sockets,Network Programming,Recv,我正在用新设计的协议实现一台服务器。按照协议,客户机发送头,后跟数据。标头包含元信息,包括数据大小 我们提供示例客户端,但客户端程序也可以由第三方编写。所以,我们不能完全依赖于报头中提供的数据字段的大小 现在,我面临一个有关recv()系统调用的问题 #define SOCKET_CHUNK_SIZE 4096 void * value; 1 value = (void *) malloc(hdr.size); 2 total_bytes_read =
recv()
系统调用的问题
#define SOCKET_CHUNK_SIZE 4096
void * value;
1 value = (void *) malloc(hdr.size);
2 total_bytes_read = 0;
3 while(total_bytes_read < hdr.size) {
4 n = recv(newsockfd, value + total_bytes_read, SOCKET_CHUNK_SIZE, 0);
5
6 //fprintf(stderr, " %ld + %d = %ld\n", total_bytes_read, n, total_bytes_read + n);
7
8 total_bytes_read += n;
9
10 if(n == 0 || n < SOCKET_CHUNK_SIZE)
11 break;
12 if(n < 0)
13 send_error_response(newsockfd);
14 }
15
16 fprintf(stderr, "%ld", total_bytes_read);
#定义套接字块大小4096
无效*值;
1值=(void*)malloc(hdr.size);
2总字节数\u读取=0;
3 while(总字节读取
这对少量数据(如9420字节)非常有效,但对较大数据量无效
观察:
让客户端发送大量数据,如604697字节(hdr.size):
recv()
只能读取65280字节。i、 e.fprintf在线打印16张65280张。(我在我的机器上检查了SSIZE_MAX,它是2147483647,所以它远远大于SOCKET_CHUNK_大小)recv()
调用中使用MSG_DONTWAIT标志,但结果相同read()
系统调用代替recv()
,结果是一样的recv()
中使用MSG_WAITALL标志,它可以工作,但在读取最后一个块时会阻塞,因为最后一个块大小小于套接字块大小(604697=147*4096+2585)。所以,我不能使用这个标志,除非我依赖于客户端头中提供的大小并在recv()
中进行更改拉维几乎所有的观察结果都可以完全解释:
因此,从我的观点来看,最好的办法是在不使用MSG_WAITALL标志的情况下使用recv,并接受小于SOCKET_CHUNK_SIZE的接收块。
n
此条件不好。一个recv
调用接收的数据可以小于指定的字节数。在知道n>0
之前,不应增加total\u bytes\u read
。如果n<0
它将发送错误并且不接受data@Ravi如果n<0
执行total\u bytes\u read+=n
是不正确的。没有两条路可走。您应该先测试n<0
。