socket重用

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:
BOOL bReuseaddr=TRUE;
setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));


2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历
TIME_WAIT的过程:
BOOL bDontLinger = FALSE;
setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL));


3.在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缓冲区的字节
(异步);系统默认的状态发送和接收一次为8688字节(约为8.5K);在实际的过程中发送数据
和接收数据量比较大,可以设置socket缓冲区,而避免了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. 如果在发送数据的时,希望不经历由系统缓冲区到socket缓冲区的拷贝而影响
程序的性能:
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数据报的时候,希望该socket发送的数据具有广播特性:
BOOL bBroadcast=TRUE;
setsockopt(s,SOL_SOCKET,SO_BROADCAST,(const char*)&bBroadcast,sizeof(BOOL));


8.在client连接服务器过程中,如果处于非阻塞模式下的socket在connect()的过程中可
以设置connect()延时,直到accpet()被呼叫(本函数设置只有在非阻塞的过程中有显著的
作用,在阻塞的函数调用中作用不大)
BOOL bConditionalAccept=TRUE;
setsockopt(s,SOL_SOCKET,SO_CONDITIONAL_ACCEPT,(const char*)&bConditionalAccept,sizeof(BOOL));


9.如果在发送数据的过程中(send()没有完成,还有数据没发送)而调用了closesocket(),以前我们
一般采取的措施是"从容关闭"shutdown(s,SD_BOTH),但是数据是肯定丢失了,如何设置让程序满足具体
应用的要求(即让没发完的数据发送出去后在关闭socket)?
struct linger {
u_short l_onoff;
u_short l_linger;
};
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));

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

设置套接口的选项。

   #include <winsock.h>

   int PASCAL FAR setsockopt( SOCKET s, int level, int optname,
   const char FAR* optval, int optlen);

   s:标识一个套接口的描述字。
   level:选项定义的层次;目前仅支持SOL_SOCKET和IPPROTO_TCP层次。
   optname:需设置的选项。
   optval:指针,指向存放选项值的缓冲区。
   optlen:optval缓冲区的长度。

注释:
  setsockopt()函数用于任意类型、任意状态套接口的设置选项值。尽管在不同协议层上存在选项,但本函数仅定义了最高的“套接口”层次上的选项。选项影响套接口的操作,诸如加急数据是否在普通数据流中接收,广播数据是否可以从套接口发送等等。
   有两种套接口的选项:一种是布尔型选项,允许或禁止一种特性;另一种是整形或结构选项。允许一个布尔型选项,则将optval指向非零整形数;禁止一个选项optval指向一个等于零的整形数。对于布尔型选项,optlen应等于sizeof(int);对其他选项,optval指向包含所需选项的整形数或结构,而optlen则为整形数或结构的长度。SO_LINGER选项用于控制下述情况的行动:套接口上有排队的待发送数据,且closesocket()调用已执行。参见closesocket()函数中关于SO_LINGER选项对closesocket()语义的影响。应用程序通过创建一个linger结构来设置相应的操作特性:
   struct linger {
int l_onoff;
int l_linger;
   };
   为了允许SO_LINGER,应用程序应将l_onoff设为非零,将l_linger设为零或需要的超时值(以秒为单位),然后调用setsockopt()。为了允许SO_DONTLINGER(亦即禁止SO_LINGER),l_onoff应设为零,然后调用setsockopt()。
   缺省条件下,一个套接口不能与一个已在使用中的本地地址捆绑(参见bind())。但有时会需要“重用”地址。因为每一个连接都由本地地址和远端地址的组合唯一确定,所以只要远端地址不同,两个套接口与一个地址捆绑并无大碍。为了通知WINDOWS套接口实现不要因为一个地址已被一个套接口使用就不让它与另一个套接口捆绑,应用程序可在bind()调用前先设置SO_REUSEADDR选项。请注意仅在bind()调用时该选项才被解释;故此无需(但也无害)将一个不会共用地址的套接口设置该选项,或者在bind()对这个或其他套接口无影响情况下设置或清除这一选项。
   一个应用程序可以通过打开SO_KEEPALIVE选项,使得WINDOWS套接口实现在TCP连接情况下允许使用“保持活动”包。一个WINDOWS套接口实现并不是必需支持“保持活动”,但是如果支持的话,具体的语义将与实现有关,应遵守RFC1122“Internet主机要求-通讯层”中第4.2.3.6节的规范。如果有关连接由于“保持活动”而失效,则进行中的任何对该套接口的调用都将以WSAENETRESET错误返回,后续的任何调用将以WSAENOTCONN错误返回。
   TCP_NODELAY选项禁止Nagle算法。Nagle算法通过将未确认的数据存入缓冲区直到蓄足一个包一起发送的方法,来减少主机发送的零碎小数据包的数目。但对于某些应用来说,这种算法将降低系统性能。所以TCP_NODELAY可用来将此算法关闭。应用程序编写者只有在确切了解它的效果并确实需要的情况下,才设置TCP_NODELAY选项,因为设置后对网络性能有明显的负面影响。TCP_NODELAY是唯一使用IPPROTO_TCP层的选项,其他所有选项都使用SOL_SOCKET层。
   如果设置了SO_DEBUG选项,WINDOWS套接口供应商被鼓励(但不是必需)提供输出相应的调试信息。但产生调试信息的机制以及调试信息的形式已超出本规范的讨论范围。
  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头中设置选项。

返回值:
   若无错误发生,setsockopt()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。

错误代码:
   WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
   WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
   WSAEFAULT:optval不是进程地址空间中的一个有效部分。
   WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
   WSAEINVAL:level值非法,或optval中的信息非法。
   WSAENETRESET:当SO_KEEPALIVE设置后连接超时。
   WSAENOPROTOOPT:未知或不支持选项。其中,SOCK_STREAM类型的套接口不支持SO_BROADCAST选项,SOCK_DGRAM类型的套接口不支持SO_DONTLINGER 、SO_KEEPALIVE、SO_LINGER和SO_OOBINLINE选项。
   WSAENOTCONN:当设置SO_KEEPALIVE后连接被复位。
   WSAENOTSOCK:描述字不是一个套接口。

 

c/c++:端口复用(setsockopt)、io多路转接(select、 poll、epoll) 目录 1. 端口复用 setsockopt函数 2. IO多路转接 2.1select select函数演示: io多路转接(select函数)服务器代码模板 3.2poll 2.3 epoll epoll_create 创建函数 epoll_ctl 控制函数 epoll_wait检测函数 2.4 epoll 的工作模式 2.4.1LT模式(默认) epoll... 阅读详情

相关推荐

【学习笔记】socket关于端口重用的学习

这两天想写一个c2c服务器的模型

许嵩奇 1287

python udp传输 报错:OSError: [WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。

return

Dontla的博客 1万+

Python实现基于socket的udp传输与接收功能详解

本文实例讲述了Python实现基于socket的udp传输与接收功能。分享给大家供大家参考,具体如下: udp的传输与接收 windows网络调试助手下载:https://pan.baidu.com/s/1IwBWeAzGUO1A3sCWl20ssQ 提取码:68gr 或者点击此处本站下载。 一.基本用法 1.创建套接字 udp_socket = socket.socket(socket.AF_INET,cosket.SOCK_DGRAM) localaddr = (,port) udp_socket.bind(localaddr) 2.使用套接字收发数据 udp_socket.sen

setsockopt 设置socket

1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL));2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_

驱动开发 1万+

OSError: [WinError 10040] 一个在数据报套接字上发送的消息大于内部消息缓冲区或其他一些网络限制,或该用户用于接收数据报的缓冲区比数据报小。

OSError: [WinError 10040]

Matteo_Wang的博客 3303

socket 连接,使得地址马上可以重用

/* 使地址马上可以重用 */                                                                                         int nRet = 1;                                                                                  

searchwang的专栏 1030

java 端口重用_java异常socket:bind: Address already in use 端口立即重用

java异常socket:bind: Address already in use 端口立即重用socket编程时,常遇到下面的地使用错误:Cann't bind server socket !: Address already in use 。说明:可以使用 bind API 函数来绑定一个地址(一个接口和一个端口)到一个套接字端点。可以在服务器设置中使用这个函数,以便限制可能有连接到来的接口...

weixin_36193690的博客 641

socket 端口重用

使用SO_REUSEADDR选项, 处于TIME_WAIT状态(还有其他情况导致端口资源还没完全释放)的socket的端口可以被立即重用

lcxhjg的专栏 1679

socket通讯(接收、发送、地址重用等)

1. server端socket的接收机制 def accept(self): """accept() -> (socket object, address info) Wait for an incoming connection. Return a new socket representing the connection, and the address of the client. For IP sockets,

要努力成为很厉害很厉害的人哦 1385

socket地址和端口重用(造成bind出错)

其实这个问题在Richard Stevens的《Unix网络编程指南》卷一里有很详细的 解答(中文版P166-168页)。这里我只是写几个基本的例子来验证这个问题。     首先声明一个问题:当两个socket的address和port相冲突,而你又想重用地 址和端口,则旧的socket和新的socket都要已经被设置了SO_REUSEADDR特性,只 有两者之一有这个特性还是有问题的。

qq_21370599的博客 946

java对象重用_JAVA中Socket对象如何重用多次?

慕莱坞5435954不是的,你得仔细了解一下socket的读写数据机制。关闭writer和关闭socket的时候,**发现buffer有数据没有写出,会写一遍**,但不是必须关闭流和关闭socket**才会写数据**。一般是通过输出流的 write()和flush()方法,完成写操作。想要多次的输出数据,首要条件就是socket不被close和outputStream没有close...顺便给你贴...

weixin_42125192的博客 224

linux 才socket设置端口复用,[转]linux 下Socket端口重用

2009-09-04 10:58重用UDP端口要重用UDP端口,需要在绑定套接字之前将套接字设置为支持SO_REUSEADDR。当两个或多个UDP套接字绑定了同一个IP和端口后,每一个套接字都可以独立进行数据的发送,但是接收的情况却比较复杂:1、如果数据报的目的地址为常规的单播地址时,谁及时地进行了recvfrom,谁将得到该数据报,其他的套接字将无法收到该数据报。但如果在recvfrom时使用了...

weixin_30219823的博客 906

网络编程10 重用socket

因为tcp连接的TIME_WAIT时间,所以一个连接断开后不能立即复用。 此时可以改变内核的tcp_tw_reuse状态 或者在bind函数之前调用setsockopt函数设置状态 示例代码 nt main(int argc, char **argv) { int listenfd; listenfd = socket(AF_INET, SOCK_STREAM, 0); ...

qq_35975827的博客 292

socket:bind: Address already in use 端口立即重用

一。在socket编程时,常遇到下面的地使用错误: Cann't bind server socket ! : Address already in use 。 二。说明: 可以使用 bind API 函数来绑定一个地址(一个接口和一个端口)到一个套接字端点。可以在服务器设置中使用这个函数,以便限制可能有连接到来的接口。也可以在客户端设置中使用这个函数,以便限制应当供出去的连接所使用的接...

weixin_30444105的博客 325

[python&php 网络编程]重用socket地址

1.python写法 import socket def reuse_socket_addr(): sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) # Get the old state of the SO_REUSEADDR option old_state = sock.getsockopt(s

YIP 2512

java socket 复用_JAVA中Socket对象如何重用多次?

不是的,你得仔细了解一下socket的读写数据机制。关闭writer和关闭socket的时候,**发现buffer有数据没有写出,会写一遍**,但不是必须关闭流和关闭socket**才会写数据**。一般是通过输出流的 write()和flush()方法,完成写操作。想要多次的输出数据,首要条件就是socket不被close和outputStream没有close...顺便给你贴点代码public...

weixin_42128315的博客 971

linux setsockopt函数 代码实现,linux网络编程-通过setsockopt函数使socket重用

网络编程:关于linux下的setsockopt 一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用socket,要设置一下socket(在bind()绑定socket前调用setsockopt函数)unsigned int re_use_addr = 0x01;if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const void*)&am...

weixin_35268264的博客 273

linux开启tcp快速回收,linux sockettcp的time_wait的快速回收和重用

解决方法:我们可以通过调整内核参数来调整:vi /etc/sysctl.conf编辑文件,加入以下内容:net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse= 1net.ipv4.tcp_tw_recycle= 1net.ipv4.tcp_fin_timeout= 30然后执行/sbin/sysctl -p让参数生效。net.ipv4.tcp_synco...

weixin_35744893的博客 1219
上一篇: windows核心编程 宏
下一篇: Wininet CInternetSession类编程的一些心得 包括如何清空cookie
killalarm
博客等级 码龄17年 13粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值