基于TCP的半关闭

来源:互联网 发布:cpu散片淘宝店家推荐? 编辑:程序博客网 时间:2024/05/17 23:29
TCP练级的半关闭简而言之就是”关闭连接的一半”(只可以传递或接收数据)
 
套接字和流
两台主机通过套接字建立连接后进入可交换数据的状态(流形参的状态),即将建立套接字后可交换数据的状态看做一种流
套接字的流中,数据只能向一个方向移动,因此需要两个流进行双向通信(建立连接后的主机将拥有单独的输入流与输出流这两个相互独立的流,这两个流与连接上的另一个主机的输出流与输入流形相连),半关闭就是指关闭其中一个方向的流
 
Linux系统下的close函数与windows下的closesocket函数被调用后是完全的断开连接,即同时关闭了输入流与输出流,这也导致不能再发送数据也不能再接收数据


半关闭实现函数
Int shutdown(int sock, int howto);
Linux中:
成功返回0,失败返回-1
参数一需要断开的套接字的文件描述符
参数二断开方式,可取值
SHUT_RD 断开输入流           SHUT_WR断开输出流            SHUT_RDWR同时断开输入与输出流
 
Windows中:
成功返回0,失败返回SOCKET_ERROR
参数二可取值:
SD_RECEIVE 断开输入流       SD_SEND断开输出流              SD_BOTH同时断开输入与输出流
 
断开输入流:套接字将无法接受数据,即使输入缓冲收到数据也会抹去,且无法调用输入相关函数,
断开输出流:套接字无法传输数据,但输出缓冲区还留有未传输的数据,则会将未传输数据传输给目标主机
 
为什么需要半关闭
为了保证数据的完全交换,应该留出足够长的连接时间,但是应该留出多长的时间呢?
比如客户端连接到服务器,服务器将一个文件传输给客户端,客户端收到后发送确认数据给服务器端
这时服务器端只需要连续的传输文件数据,而客户端却无法知道需要接收数据到何时,客户端也不可能无休止的调用输入函数,因为这有可能导致程序阻塞(调用的函数未返回)
服务器端应该在数据发送完毕后传递EOF表示文件结束,客户端接收到EOF即停止接收数据并向服务器端发送确认数据。close函数与shutdown都可以向客户端发送EOF数据,但使用close发送EOF后也无法接收对方传输的数据了,所以使用shutdown
 
注意:即使使用了shutdown函数实现TCP套接字的半关闭,在最后依旧要使用close函数关闭套接字

基于半关闭的文件传输程序部分代码:

服务器端:

if( NULL == (fp = fopen("sendfile.c", "rb")) ){printf("fopen error\n");exit(-1);}//循环读取文件,当文件余量多余BUF_SIZE时,正常情况下返回BUF_SIZE,当余量不足时应该将余量读取并跳出循环并提示文件传输完毕while(1){read_cnt = fread(buf, 1, BUF_SIZE, fp);if( read_cnt < BUF_SIZE )//{weitr(clnt_sd, buf, read_cnt);break;}write(clnt_sd, buf, BUF_SIZE);}shutdown(clnt_sd, SHUT_WR);//半关闭发送EOFfclose(fp);//别忘了close(clnt_sd), close(serv_sd);

客户端
if( NULL == (fp = fopen("recvfile.c", "wr"))){printf("fopen error\n");exit(-1);}while(0 != (read_cnt = read(sd, buf, BUF_SIZE)))fwrite(buf, 1, read_cnt, fp);write(sd, "Thank you", 10);fclose(fp);close(sd);

fread函数的注意点:
http://blog.csdn.net/foxliucong/article/details/4736956
https://my.oschina.net/u/2404244/blog/715461
http://blog.csdn.net/abclixu123/article/details/8284680
fopen函数参考:
http://blog.csdn.net/borenbao/article/details/849640








0 0
原创粉丝点击