免费做app页面的网站,怎样将自己做的网站发布到外网上,沈阳妇科医院排名前十有哪些,山西省建设厅网站打不开1、socket缓冲区
每一个socket在被创建之后#xff0c;系统都会给它分配两个缓冲区#xff0c;即输入缓冲区和输出缓冲区。 #xff08;1#xff09;send函数并不是直接将数据传输到网络中#xff0c;而是负责将数据写入输出缓冲区#xff0c;数据从输出缓冲区发送到目标…1、socket缓冲区
每一个socket在被创建之后系统都会给它分配两个缓冲区即输入缓冲区和输出缓冲区。 1send函数并不是直接将数据传输到网络中而是负责将数据写入输出缓冲区数据从输出缓冲区发送到目标主机是由TCP协议完成的。数据写入到输出缓冲区之后send函数就可以返回了数据是否发送出去是否发送成功何时到达目标主机都不由它负责了而是由协议负责。 2recv函数也是一样的它并不是直接从网络中获取数据而是从输入缓冲区中读取数据。 输入输出缓冲区系统会为每个socket都单独分配并且是在socket创建的时候自动生成的。一般来说默认的输入输出缓冲区大小为8K。套接字关闭的时候输出缓冲区的数据不会丢失会由协议发送到另一方而输入缓冲区的数据则会丢失。
2、socket数据发送与接收问题
数据的发送和接收是独立的并不是发送方执行一次send接收方就执行一次recv。recv函数不管发送几次都会从输入缓冲区尽可能多的获取数据。如果发送方发送了多次信息接收方没来得及进行recv则数据堆积在输入缓冲区中取数据的时候会都取出来。换句话说recv并不能判断数据包的结束位置。 send函数 在数据进行发送的时候需要先检查输出缓冲区的可用空间大小如果可用空间大小小于要发送的数据长度则send会被阻塞直到缓冲区中的数据被发送到目标主机有了足够的空间之后send函数才会将数据写入输出缓冲区。 TCP协议正在将数据发送到网络上的时候输出缓冲区会被锁定生产者消费者问题不允许写入send函数会被阻塞直到数据发送完输出缓冲区解锁此时send才能将数据写入到输出缓冲区。 要写入的数据大于输出缓冲区的最大长度的时候要分多次写入直到所有数据都被写到缓冲区之后send函数才会返回。 recv函数 函数先检查输入缓冲区如果输入缓冲区中有数据读取出缓冲区中的数据否则的话recv函数会被阻塞等待网络上传来数据。如果读取的数据长度小于输出缓冲区中的数据长度没法一次性将所有数据读出来需要多次执行recv函数才能将数据读取完毕。
3、完整的发送和接收数据代码 // 读取文件数据发送
const int _buffer_size 1024;
char buffer[_buffer_size] {0}; // 缓冲区
int nCount;
while( (nCount fread(buffer, 1, _buffer_size, fp)) 0 ){ // 当读取到文件末尾fread() 会返回 0结束循环send(sock, buffer, nCount, 0);
}
shutdown(sock, SHUT_WR); // 文件读取完毕断开输出流向对方发送FIN包
recv(sock, buffer, _buffer_size, 0); // 阻塞等待对方接收完毕此时recv()没有接收到对方数据当对方关闭socket后这边会收到FIN包recv()就会返回再执行后面的代码注意读取完缓冲区中的数据 recv() 并不会返回 0而是被阻塞直到缓冲区中再次有数据。
recv() 返回 0 的唯一时机是收到FIN包FIN 包表示数据传输完毕计算机收到 FIN 包后表示对方不再向自己传输数据。
当调用 read()/recv() 函数时如果缓冲区中没有数据就会返回 0表示读到了”socket文件的末尾“。
可以调用 shutdown() 来发送FIN包server 端直接调用 close()/closesocket() 会使输出缓冲区中的数据
失效文件内容很有可能没有传输完毕连接就断开了而调用 shutdown() 会等待输出缓冲区中的数据传输完毕。// 收到数据写入文件important
const int _buffer_size 1024;
char buffer[_buffer_size] {0}; // 缓冲区
int nCount;
while( (nCount recv(sock, buffer, _buffer_size, 0)) 0 ){fwrite(buffer, nCount, 1, fp);
}
close(sock); // 文件接收完毕后直接关闭套接字无需调用shutdown()