c++从套接字读取未知量的数据
c++ read unknow amount of data from socket
我在c++
中编写了一个简单的tcp/ip
连接client-server
。
这是服务器处理连接的部分
int sockfd, newsockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n = 0;
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0){
cout << "Error opening socket" << endl;
exit(1);
}
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr))<0){
cout << "Error binding" << endl;
exit(1);
}
listen(sockfd,1);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr *)&cli_addr, &clilen );
if(newsockfd < 0){
cout << "Error accepting" << endl;
exit(1);
}
bzero(bytes,size_tot);
uint64_t total_bytes_read = 0;
uint64_t total_bytes_to_read = size_tot;
while(total_bytes_read < total_bytes_to_read){
int bytes_read = read(newsockfd,bytes + total_bytes_read,total_bytes_to_read - total_bytes_read);
if(bytes_read == -1){
cout << "error reading "<< endl;
n = -1;
break;
}
total_bytes_read += bytes_read;
}
但如果我知道要读取的字节总数,这就行了。如果要读取的数据总量未知,该怎么办?我如何修改这段代码?
您询问了如何修复低级接收代码。这很简单——只需调用read
一次,而不使用while
循环。只要能够读取至少一个字节的数据,对read
的调用就会返回。对于要读取的字节数,只需输入缓冲区的大小(或者如果之前的调用已经有剩余的空间,则输入缓冲区中剩余的空间)。
您还需要高级协议代码,就像您知道字节数一样。该代码可能需要有所不同。如果你得到的字节块包括你的停止指示,那么处理直到停止指示的所有字节,并将多余的字节保留在缓冲区中以备下次使用。如果没有,只需再次调用read
并获得更多字节。
您的协议处理代码应该是这样的:
- 调用
read
并向缓冲区添加任意数量的字节。(在此处处理错误或正常关闭。) - 如果缓冲器中的数据不包括停止指示,则转到步骤1
- 处理所有字节直到停止指示
- 从缓冲区中删除已处理的字节,保留所有未处理的字节
- 转至步骤2
此外,如果对方关闭连接,你在问题中给出的代码将永远旋转。在这种情况下,read
将返回零,您将永远无法从连接中读取更多数据。如果read
返回零,则应该脱离循环。
首先,去掉所有bzero
调用。我不知道为什么这一点不断地渗透到好人的代码中。不需要这个。
其次,您需要以某种方式预先通知传输的大小(例如,HTTP 1.1在标头中提供了此信息),或者简单地声明一旦传输了所有数据,连接就关闭了——这将是HTTP 1.0模型。
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- c++从套接字读取未知量的数据