C中的服务器/套接字编程:数据未正确发送/接收?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C中的服务器/套接字编程:数据未正确发送/接收?相关的知识,希望对你有一定的参考价值。
我正在编写一个侦听连接的服务器端程序。当它收到一个时,它会产生一个分离的线程并处理连接。我希望它能够接收从客户端发送的几行数据,并将其存储在数据结构中(所以我可以稍后对其进行排序)。
客户端这样做:
- 获取.csv文件的文件大小
- 将filesize发送到服务器
- 打开.csv
- 使用fgets()检索一行并将其放入缓冲区
- 将此行的字节数发送到服务器
- 将该行的数据发送到服务器
目标是逐行发送数据,并将每一行存储在服务器端的结构中。问题是,数据没有被发送过来。似乎单个发送请求被切断并在两个不同的recv()调用中处理。
客户端发送循环:
void sendData(int sock, FILE* fd){
char data[BUFFER];
int32_t filesize;
printf("seeking
");
if((fseek(fd, 0L, SEEK_END)) == ERROR){
fprintf(stderr, "An error has occured: %s
", strerror(errno));
exit(EXIT_FAILURE);
};
if((filesize = ftell(fd)) == ERROR){
fprintf(stderr, "An error has occured: %s
", strerror(errno));
exit(EXIT_FAILURE);
};
rewind(fd);
// subtracting bytes for the col headers
//filesize -= COLSIZE;
fgets(data, sizeof(data), fd);
printf("strlen of data: %d
", (int)strlen(data));
printf("
filesize: %ld
", (long)filesize);
filesize = filesize - strlen(data);
printf("
filesize: %ld
", (long)filesize);
// converting data len to net order
filesize = htonl(filesize);
char* len_data = (char*)&filesize;
// sending filesize
printf("sending filesize
");
send(sock, len_data, sizeof(int32_t), 0);
filesize = ntohl(filesize);
printf("
filesize: %ld
", (long)filesize);
// grabbing first line and sending
//printf("fgetting test
");
while(filesize > 0){
while(fgets(data, sizeof(data), fd) != NULL){
if(data[strlen(data) - 1] == '
'){
printf("
taking newline out
");
data[strlen(data) - 1] = ' ';
}
// getting and sending size of the line
int32_t dataSize = sizeof(char)*strlen(data);
printf("data size of line: %d
", dataSize);
dataSize = htonl(dataSize);
char* lineSize = (char*)&dataSize;
int j = send(sock, lineSize, sizeof(int32_t), 0);
printf("size of data sent: %d
", j);
// sending the line
printf("line of data: %s
", data);
int i = send(sock, data, sizeof(char)*strlen(data), 0);
printf("size of data sent: %d
", i);
filesize -= i;
printf("new filesize: %d
", filesize);
}
}
客户输出:
taking newline out
data size of line: 303
size of data sent: 4
line of data: Color,Andrew Stanton,462,132,475,530,Samantha Morton,640,73058679,Action|Adventure|Sci-Fi,Daryl Sabara,John Carter ,212204,1873,Polly Walker,1,alien|american civil war|male nipple|mars|princess,http://www.imdb.com/title/tt0401729/?ref_=fn_tt_tt_1,738,English,USA,PG-13,263700000,2012,632,6.6,2.35,24000
size of data sent: 303
new filesize: 1001
服务器接收循环:
int32_t linesize;
int32_t filesize;
// set to 1 to attempt to receive bytes
receive_int(&filesize,sock_info->sock);
printf("Recieving file size %d
", filesize);
// wait for a recv
while(filesize){
printf("
Current File Size: %ld
",(long) filesize);
receive_int(&linesize,sock_info->sock);
printf("Line size: %ld
", (long)linesize);
char* filebuf = (char*)malloc(sizeof(char)*linesize);
printf("size of filebuf: %d
", sizeof(*filebuf));
int i = recv(sock_info->sock, filebuf, sizeof(char)*linesize, 0);
printf("strlen of filebuf: %d
", strlen(filebuf));
printf("number of bytes received: %d
", i);
printf("Received msg: %s
",filebuf);
filesize -= i;
}
服务器输出
Current File Size: 1304
Line size: 303
size of filebuf: 1
strlen of filebuf: 165
number of bytes received: 165
Received msg: Color,Andrew Stanton,462,132,475,530,Samantha Morton,640,73058679,Action|Adventure|Sci-Fi,Daryl Sabara,John Carter ,212204,1873,Polly Walker,1,alien|american civil
Current File Size: 1139
Line size: 2002875004
size of filebuf: 1
strlen of filebuf: 134
number of bytes received: 1139
Received msg: male nipple|mars|princess,http://www.imdb.com/title/tt0401729/?ref_=fn_tt_tt_1,738,English,USA,PG-13,263700000,2012,632,6.6,2.35,24000
答案
正如man
的recv
页面所示:
接收呼叫通常会返回任何可用的数据,直到请求的数量,而不是等待收到所请求的全部金额。
正如man
的send
页面所示:
使用零标志参数,send()等效于write(2)。 ...成功时,这些调用返回发送的字节数。
正如man
的write
页面所示:
写入从缓冲区计数字节从...开始
如您所见,网络send
和recv
不保证实际发送的数据长度或每个函数调用中接收的数据长度。
此外,随着分组在网络中移动,将单个分组分段为多个分组(例如,由于网络MTU设置的差异),这是非常常见的。
处理网络数据的唯一方法是连续流。
为了找到新的线标记,接收端点必须连接任何接收的数据并沿着新的线标记切断。
我建议Beej's guide作为启动网络编码的良好资源。
祝好运。
以上是关于C中的服务器/套接字编程:数据未正确发送/接收?的主要内容,如果未能解决你的问题,请参考以下文章