免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 16568 | 回复: 7
打印 上一主题 下一主题

[socket]如何解除绑定bind()? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-05-11 18:29 |只看该作者 |倒序浏览
在用socket时,Server端创建一个socket后,退出时如何解除绑定呢?
在我的程序中,创建socket后,Server与Client通信正常,但是在Server端主动停止接收和发送数据后(设置了一个停止按钮),然后再启动Server时,会出现bind error。请教各位,该如何解决这个问题。谢谢。。。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2005-05-11 18:32 |只看该作者

[socket]如何解除绑定bind()?

close()
for win: closesocket()

论坛徽章:
0
3 [报告]
发表于 2005-05-11 20:00 |只看该作者

[socket]如何解除绑定bind()?

我用了close()了,可还是出现了bind error!
在bind出错时,程序是这样写的:
perror("bind error";
exit(1);
出现的错误信息是:bind error:No error
让人莫名其妙!
不知道是为什么。
另外,这跟Client的程序有关么?

论坛徽章:
0
4 [报告]
发表于 2005-05-11 20:11 |只看该作者

[socket]如何解除绑定bind()?

你去查查什么叫TIME_WAIT状态就懂了(如果我没猜错的话)

"没解除绑定"这个说法还头一次听说,呵呵。用setsockopt更改属性可以listen端口在time_wait状态下也能启动的。

论坛徽章:
0
5 [报告]
发表于 2005-05-11 22:00 |只看该作者

[socket]如何解除绑定bind()?

int enable = 1;
setsockopt(socket, SOL_SOCKET, SO_REUSEADDR,  &enable, sizeof(int);
好象是这样

论坛徽章:
0
6 [报告]
发表于 2005-05-12 11:32 |只看该作者

[socket]如何解除绑定bind()?

原帖由 "caojiqun" 发表:
int enable = 1;
setsockopt(socket, SOL_SOCKET, SO_REUSEADDR,  &enable, sizeof(int);
好象是这样

确实可以工作了,多谢!

论坛徽章:
0
7 [报告]
发表于 2005-05-12 11:33 |只看该作者

[socket]如何解除绑定bind()?

我找的关于setsockopt的资料:
1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用
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));
Note:1.在设置了逗留延时,用于一个非阻塞的socket是作用不大的,最好不用;
     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));

论坛徽章:
0
8 [报告]
发表于 2005-05-12 13:09 |只看该作者

[socket]如何解除绑定bind()?

近来看看真实受益非浅呀
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP