setsockopt函数使用,setsockopt参数详解

  setsockopt函数使用,setsockopt参数详解

  1.如果要从已经处于建立状态的套接字(一般用端口号和标识符区分)调用closesocket后继续重用套接字(一般不会立即关闭,要经历TIME_WAIT的过程):

  BOOL bReuseaddr=TRUE

  setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(const char*) bReuseaddr,sizeof(BOOL));

  2.如果您希望在调用closesocket后强制关闭已连接的套接字,请不要体验

  时间等待程序:

  BOOL bDontLinger=FALSE

  setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*) bDontLinger,sizeof(BOOL));

  3.在SEND () send()、recv()的过程中,有时由于网络条件等原因,收发无法预期,设置了收发时限:

  int nNetTimeout=1000//1秒

  //发送时间限制

  setsockopt(socket,SOL _ S0CKET,SO_SNDTIMEO,(char *) nNetTimeout,sizeof(int));

  //接收时间限制

  setsockopt(socket,SOL _ S0CKET,SO_RCVTIMEO,(char *) nNetTimeout,sizeof(int));

  4.send()时,返回的是实际发出的字节(同步)或发送到socket buffer的字节(异步);系统默认状态是8688字节(约8.5k)收发一次;实际过程中收发数据量比较大,可以设置socket缓冲区,避免send () send()、recv()不断循环收发:

  //接收缓冲区

  int nRecvBuf=32 * 1024//设置为32K

  setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*) nRecvBuf,sizeof(int));

  //发送缓冲区

  int nSendBuf=32 * 1024//设置为32K

  setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*) nSendBuf,sizeof(int));

  5.如果在发送数据时,希望从系统缓冲区到套接字缓冲区的复制不会影响程序的性能:

  int nZero=0;

  setsockopt(socket,SOL _ S0CKET,SO_SNDBUF,(char *) nZero,sizeof(nZero));

  6.同上,在recv()中完成上述函数(默认情况下,将socket缓冲区的内容复制到系统缓冲区):

  int nZero=0;

  setsockopt(socket,SOL _ S0CKET,SO_RCVBUF,(char *) nZero,sizeof(int));

  7.通常,当发送UDP数据报时,希望该套接字发送的数据具有广播特征:

  BOOL bBroadcast=TRUE

  setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*) bBroadcast,sizeof(BOOL));

  8.在客户端连接服务器的过程中,如果非阻塞模式的socket处于connect()过程中,可以设置connect()延迟,直到调用accpet()为止(该函数设置只在非阻塞过程中起显著作用,在阻塞的函数调用中不起作用)

  BOOL bConditionalAccept=TRUE

  setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char *)bconditionaccept,sizeof(BOOL));

  9.如果在发送数据的过程中调用了close socket()(send()没有完成,还有数据没有发送),我们之前通常采取的措施是‘从容关闭’shut down(s,SD_BOTH),但是数据肯定是丢失了。如何设置程序以满足特定应用的要求(即发送完未完成的数据后关闭套接字)?

  结构逗留{

  u _ short l _ onoff

  u _ short l _ linger

  };

  灵儿m _ sLinger

  m _ slinger . l _ onoff=1;//(调用closesocket()时允许停留,但仍有数据要发送)

  //如果m _ slinger . l _ onoff=0;功能与2相同。);

  m _ slinger . l _ linger=5;//(允许的停留时间为5秒)

  setsockopt(s,SOL_SOCKET,SO_LINGER,(const char*) m_sLinger,sizeof(LINGER));

  注:1。在设置了停留延迟的情况下,对于非阻塞套接字来说用处不大,最好不要使用;

  2.如果想让程序不经历SO_LINGER,需要设置SO_DONTLINGER或者设置L _ ONOFF=0;

  10.另一个较少使用的程序是可以在SDI或Dialog程序中记录socket的调试信息:

  (我前不久做过这个功能的测试,模式信息可以保存,包括socket建立时的参数。这

  可以记录特定的协议以及错误代码)

  BOOL bDebug=TRUE

  setsockopt(s,SOL_SOCKET,SO_DEBUG,(const char*) bDebug,sizeof(BOOL));

  1.附加:缓冲区大小常由setsockopt()设置,但不能满足数据传输要求。

  我的习惯是写一个处理网络缓冲的类,动态分配内存。下面我就写这个类,希望是对的。

  初学者很有帮助:

  //是模仿String重写的。

  //==============================================================================

  //二进制数据,主要用于收发网络缓冲区的数据

  //cnetiobffer以MFC(消歧义)类c环!c环!c形环的源代码作为蓝本改写而成,用法与c环!c环!c形环类似,

  //但是壳聚糖缓冲剂公司中存放的是纯粹的二进制数据,/0 并不作为它的结束标志。

  //其数据长度可以通过GetLength()获得,缓冲区地址可以通过运算符LPBYTE(字节)获得。

  ===ytet-伊甸园字幕组=-翻译:粒粒尘紫月猫姐风景校对

  //版权所有全视公司.保留所有权利。

  //模块:网络对象

  //文件:simpleiobuffer。h

  //作者:gdy 119

  //电子邮件:8751网站管理员@126.com

  //日期:2004年11月26日

  ===ytet-伊甸园字幕组=-翻译:粒粒尘紫月猫姐风景校对

  //NetIOBuffer.h

  #ifndef _NETIOBUFFER_H

  #define _ netiobuffer _ h

  ===破烂熊乐园倾情奉献=================破烂熊乐园倾情奉献=============================================破烂熊乐园倾情奉献

  #设置最大缓冲区长度1024*1024

  ===破烂熊乐园倾情奉献=================破烂熊乐园倾情奉献=============================================破烂熊乐园倾情奉献

  //主要用来处理网络缓冲的数据

  壳聚糖缓冲剂级战列舰

  {

  受保护:

  S7-1200可编程控制器:

  内部m _长度

  内部蒙托塔伦思

  临界_截面_cs:

  void init valbers();

  观众:

  cnetiobffer();

  cnetiobifer(const LP byte lb byte,int nlngth);

  cnetiobifer(const cnetiobifer binary src);

  virtual ~ cnetiobfer();

  ===破烂熊乐园倾情奉献=============破烂熊乐园倾情奉献=================================================破烂熊乐园倾情奉献

  BOOL CopyData(const LPBYTE lbbyte,int nlngth);

  bool concat data(const LP byte lb byte,int lnngth);

  空的重置缓冲区();

  int get length()常量;

  bool setlength(int nln);

  LP byte getcurpos();

  int getrmainlen();

  bool isempty()const;

  LPBYTE()常量运算符;

  静态获取axlength(){返回最大缓冲区长度}

  const cnetiobuffer运算符=(const cnetiobuffer buf src);

  }:

  #endif //

  //NetOBuffer.cpp:实施cnobuffer类。

  ===ytet-伊甸园字幕组=-翻译:粒粒粒尘紫月猫姐风景校对:阿衡时间轴:邦德猪

  #包括stdafx.h

  #包括netiobuffer。h

  ===ytet-伊甸园字幕组=-翻译:粒粒粒尘紫月猫姐风景校对:阿衡时间轴:邦德猪

  ===ytet-伊甸园字幕组=-翻译:粒粒粒尘紫月猫姐风景校对:阿衡时间轴:邦德猪

  //构造/销毁

  cnetiobifer:cnetiobifer()

  {

  init val bers();

  }

  cnetiobifer:cnetiobifer(const LP byte lb byte,int nlength)

  {

  init val bers();

  CopyData(lbbyte、nlngth);

  }

  cnetiobifer:~ cnetiobifer()

  {

  删除[]m _ pbin data;

  m_pbinData=NULL:

  deletecriticalsection函数(m_cs):

  }

  cnetiobifer:cnetiobifer(const cnetiobifer binary src)

  {

  init val bers();

  CopyData(binarySrc,binarySrc).get length());

  }

  见cnetiobffer:init validbers()

  {

  m_pbinData=NULL:

  m _ nlngth=0;

  m_nTotalLength=最大缓冲区_长度:

  if(m_pbinData==NULL)

  {

  m _ pbindata=new新字节[m _ ntotallength];

  断言(m_pbinData!=空:

  }

  初始化部分(m _ cs):

  }

  请参阅cnetiobffer:reseiobuffer()

  {

  entercriticalsection函数(m_cs):

  m _ nlngth=0;

  memset(m_pbinData,0,m _ ntotallength);

  leavecriticalsection函数(m_cs):

  }

  bool cnetiobffer:复制数据(const lpbyte lbbyte,int nlength)

  {

  如果(最大缓冲区长度)

  返回错误的

  复位缓冲区():

  entercriticalsection函数(m_cs):

  memcpy(m_pbinData、lbbyte、nlngth);

  m _ nlength=nlength

  leavecriticalsection函数(m_cs):

  返回真实的

  }

  bool cnetiobffer:concat data(const LP byte lb byte,int nlength)

  {

  if(m _ nlngth最大缓冲区_长度)

  返回错误的

  entercriticalsection函数(m_cs):

  memcpy(m _ pbindata m _ nlngth,lbbyte,lnngth);

  m _ nlength=nlength

  leavecriticalsection函数(m_cs):

  返回真实的

  }

  int cnetiobifer:get ength()const

  {

  返回m _长度

  }

  bool cnetiobffer:setlength(int nln)

  {

  if(nln最大缓冲区长度)

  返回错误的

  entercriticalsection函数(m_cs):

  m _ nlength=nlen

  leavecriticalsection函数(m_cs):

  返回真实的

  }

  lpbyte techobffer:get uros()

  {

  if(m _ nlength max _ buffer _ length)

  返回(m _ pbin data m _ nlngth);

  其他语句

  返回空:

  }

  cnetiobffer:lpbyte()运算子常数

  {

  返回m _ pbindata

  }

  int cnetiobffer:getrmainlen()

  {

  返回最大缓冲区长度-m _ n长度:

  }

  bool cnetiobffer:isempty()常量

  {

  返回m _ nlngth==0;

  }

  const CNetIOBuffer CNetIOBuffer:operator=(const CNetIOBuffer buffer src)

  {

  if( buffSrc!=这个)

  {

  CopyData(buffSrc,buffSrc。GetLength());

  }

  返回* this

  }

  回复:PiggyXP

  事实上,我认为应该注意第5条。

  int nZero=0;

  setsockopt(socket,SOL _ S0CKET,SO_SNDBUF,(char *) nZero,sizeof(nZero));

  记得之前有朋友讨论过,虽然socket发送成功,但实际上只是发送到了数据缓冲区,并没有真正在物理设备上发送出去;有了这个语句,发送缓冲区设置为0,也就是发送缓冲区被阻塞后,一旦返回send(当然是以阻塞绑定字来说),就可以确定数据已经在发送_的路上了,但这可能会影响系统的性能。

  收件人:桑德()

  UDP也有复制过程,但是UDP包的最大限制是64K;

  TCP_NODELAY一般用在普通数据流上;

  12.发送数据时,通常是在系统缓冲区满了之后发送。现在只要系统设置好了

  缓冲区中有数据时立即发送数据:

  BOOL bNodelay=TRUE

  SetSockOpt(s,IPPROTO_TCP,TCP_NODELAY,(const char*) bNodelayt,sizeof(BOOL));

  回复:od4ys(峰峰)

  当setoptsock()函数设置为端口重用时,很容易损害一些没有单独绑定模式的程序。

  比如老的ping icmp门,经过简单的嗅探器,接收到数据包,然后设置setoptsock bind web服务,然后建立一个cmd进程绑定和端口80。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: