基于TCP的socket编程

11 篇文章 0 订阅

server端:


client 端:




一个server在和两个client聊天~~~

步骤:server端  1)调用socket(),创建套接字,返回值是文件描述符。

                       2)调用bind(),绑定ip和端口号。

                       3)调用listen(),监听等待连接状态的客户端。

                       4)调用accept(),接受连接,如果没有客户端连接,就以阻塞方式等待,返回值是文件描述符,注意accept拿到的是已经三次握手之后的连接

                       5)读写数据,因为tcp提供的是全双工的通信,所以既可以读,也可以写。

         client端   1)调用connect(),主动请求连接

                       2)读写数据。

          因为客户端不需要固定的端口号,因此不必调用bind(),客户端的端口号由内核自动分配。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

终止这两个进程的时候,如果先终止server端,后终止client端,之后立即启动server端,会出现这种情况:


地址已经被使用。

但是过几分钟,再启动server,就不会有这样的问题,或者先终止client端,后终止server端,也不会有这样的问题。

TCP协议规定,主动关闭连接的一方要处于TIME_WAIT状态,等待两个MSL(maximum segment lifetime)的时间后才能回到CLOSED状态,而被动关闭的一方则直接转CLOSE状态。

当一个socket关闭的时候,是通过两端互发信息的四次挥手过程完成的。所以必须完全正确的传输四次握手的四个节,不能有任何的丢失。

但是1)没有任何机制保证最后的一个ACK能够正常传输到网络上2)网络上可能有残余的数据包(wandering duplicates),我们也必须能够正常处理。

TIME_WAIT就是为了解决这两个问题而生的。


1)假设最后一个ACK丢失了,被动关闭一方会重发它的FIN。所以主动关闭一方必须维持一个有效状态信息(TIMEWAIT状态下维持),以便能够重发ACK。


2)假设目前连接的通信双方都已经调用了close(),双方同时进入CLOSED的终结状态,而没有走TIME_WAIT状态。会出现如下问题,现在有一个新的连接被建立起来,使用的IP地址与端口与先前的完全相同,后建立的连接是原先连接的一个完全复用。还假定原先的连接中有数据报残存于网络之中,这样新的连接收到的数据报中有可能是先前连接的数据报。为了防止这一点,TCP不允许新连接复用TIME_WAIT状态下的socket。处于TIME_WAIT状态的socket在等待两倍的MSL时间以后,将会转变为CLOSED状态。这就意味着,一个成功建立的连接,必然使得先前网络中残余的数据报都丢失了。


MSL是一个数据报在网络上单向发出到确认丢失的时间,一个数据报有可能在发送过程中或是响应过程中成为残余数据报,所以需要两倍的MSL

虽然TIME_WAIT对我们是有利的,但有时候我们也希望避免等待的情况,让服务器可以马上跑起来。

解决方法:在socket()和bind()调用之间插入如下代码:

int opt = 1;
setsockopt(listen_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值