网络编程小结

做了一个转发TCP 和UDP的服务端,但是现在测试老有问题,就是UDP总会有那么几次超时,原因还没找到,不过先总结一下网络的编程。

首先默认的状态下,recvfrom和recv都是阻塞的状态,也就是没接收到会一直阻塞,知道返回,但是可以通过select设置超时:

TIMEVAL tWait;
  tWait.tv_sec = 0;
  tWait.tv_usec = 1000000; // wait for 10000us

  fd_set revSet;
  FD_ZERO(&revSet);//清零
  FD_SET(AcceptSocket, &revSet); //将套接字加入描述符  

  int iResult = select(1, &revSet, NULL, NULL, &tWait);//在10ms内判断对应的socket是否可读,若刻度,立即返回套接字个数,若10ms内不可读,则返回0,然后return,结束此函数。
  if ( iResult == 0 )
  {
   printf("[TCP]--Connection from client %d.%d.%d.%d closed.\n", ClientAddr.sin_addr.s_net, \
                    ClientAddr.sin_addr.s_host, \
                    ClientAddr.sin_addr.s_lh, \
                    ClientAddr.sin_addr.s_impno);
   return;
  }
  else if ( SOCKET_ERROR == iResult )
  {
   printf("[TCP]--Connection from Client %d.%d.%d.%d error.\n", ClientAddr.sin_addr.s_net, \
                   ClientAddr.sin_addr.s_host, \
                   ClientAddr.sin_addr.s_lh, \
                   ClientAddr.sin_addr.s_impno);
   return;
  }

现在初步的判断是接受缓冲区的问题,不过对于缓冲区还有一点迷惑:

接受缓冲区是有数据就立即接受,但是发送缓冲区是等最大500ms(好像是),然后将这个时间接到的所有数据一起发送(异步),或者一个数据足够大后直接发送,这点我不是很确定。

缓冲区有数据就立刻发送缓冲区的设定如下:

BOOL bNodelay=TRUE;
 setsockopt(AcceptSocket,IPPROTO_TCP,TCP_NODELAY,(const char*)&bNodelay,sizeof(BOOL));//缓冲区有数据就立刻发送,IPPROTO_TCP选项是bool型,即费0则1,而SOL_SOCKET是实在的数,TCP_NODELAY 禁止发送合并的Nagle算法,其他类似的如下:

 setsockopt()支持下列选项。其中“类型”表明optval所指数据的类型。

  选项 类型 意义

  SO_BROADCAST BOOL 允许套接口传送广播信息。

  SO_DEBUG BOOL 记录调试信息。

  SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。设置本选项相当于将SO_LINGER的l_onoff元素置为零。

  SO_DONTROUTE BOOL 禁止选径;直接传送。

  SO_KEEPALIVE BOOL 发送“保持活动”包。

  SO_LINGER struct linger FAR* 如关闭时有未发送数据,则逗留。

  SO_OOBINLINE BOOL 在常规数据流中接收带外数据。

  SO_RCVBUF int 为接收确定缓冲区大小。

  SO_REUSEADDR BOOL 允许套接口和一个已在使用中的地址捆绑(参见bind())。

  SO_SNDBUF int 指定发送缓冲区大小。

  TCP_NODELAY BOOL 禁止发送合并的Nagle算法。

  setsockopt()不支持的BSD选项有:

  选项名 类型 意义

  SO_ACCEPTCONN BOOL 套接口在监听。

  SO_ERROR int 获取错误状态并清除。

  SO_RCVLOWAT int 接收低级水印。

  SO_RCVTIMEO int 接收超时。

  SO_SNDLOWAT int 发送低级水印。

  SO_SNDTIMEO int 发送超时。

  SO_TYPE int 套接口类型。

  IP_OPTIONS 在IP头中设置选项。

 http://baike.baidu.com/view/569217.htm

 记得以前有些朋友讨论过,socket虽然send成功了,但是其实只是发送到数据缓冲区里面了,而并没有真正的在物理设备上发送出去;而通过这条语句,将发送缓冲区设置为0,即屏蔽掉发送缓冲以后,一旦send返回(当然是就阻塞套结字来说),就可以肯定数据已经在发送的途中了^_^,但是这样做也许会影响系统的性能


to:Sander()
UDP也有拷贝过程,但是UDP包有最大限制为64K;
TCP_NODELAY 一般用在the normal data stream 上;
12.发送数据时候一般是系统缓冲区满以后才发送,现在设置为只要系统
缓冲区有数据就立刻发送:
BOOL bNodelay=TRUE;
SetSockOpt(s,IPPROTO_TCP,TCP_NODELAY,(const char*)&bNodelayt,sizeof(BOOL));

 UDP丢包是不可避免的,你可以把每个包用一个字段标识,对一部分发两遍,另外还有其他的方法,如包设置大小,发送时注意SLEEP(n),n1-10等方法

Q:本地同时与多个主机建立连接,如果这些主机同时发生数据到本地,而本地又没有调用recv进行处理,会出现什么情况?

A:系统为每个socket建立一个缓存,ip层组包进程在收到数据包后会把数据放入socket缓存。调用recv将socket缓存的内容copy到程序定义的缓存,如果通信进程不能及时recv,将导致该socket缓存满。如果用tcp协议,socket缓存满以后,系统会向对方发出错误消息,对方回收到wsaewouldblock错误,如果是用udp协议,系统会把该socket的以后收到的数据丢弃~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值