郁闷了 碰上妖怪问题了 Connect竟然不能工作了!!!!!!!

FlyOverSea 2006-11-23 11:17:45
CSocket sock;
BOOL ret = sock.Create(20567);
if (!ret)
{
AfxMessageBox("建立失败");
}
ret = sock.Connect("www.163.com", 80);
if (!ret)
{
if (WSAEADDRINUSE == WSAGetLastError())
{
AfxMessageBox("Err_1");
}
else
{
AfxMessageBox("Err_2");
}
}
sock.Close();


执行第一次没有问题,第二次开始就是弹出对话框:Err_1

郁闷了 这种事情都会发生
...全文
431 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
chengjian2006 2006-11-27
  • 打赏
  • 举报
回复
mark
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
特殊需要 我只想了解一下这个为什么不行 我也知道有其他方法可以饶过 我只是就事论事讨论这个问题而已
ouyh12345 2006-11-23
  • 打赏
  • 举报
回复
一次会话需要多次连接吗?
Eilien 2006-11-23
  • 打赏
  • 举报
回复
mark
bigarich 2006-11-23
  • 打赏
  • 举报
回复
接分
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
结贴
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
以前用过,单不是为了这个原因,我是要 UDP 和 TCP 都使用一个端口。

当时用了也的确好使。
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
ProgrameMan(程序人生)

不知道你使用过SO_REUSEADDR吗?我使用下来怎么没有效果啊(暂时不想使用linger,因为这东西会给我造成一些困挠)
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
谢谢 我试试
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
BOOL bDontLinger=FALSE;
sock.SetSockOpt(SO_DONTLINGER,(const char *)&bDontLinger,sizeof(bDontLinger),SOL_SOCKET);

好使
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
为什么TCP关闭后端口会处于TIME_WAIT状态?
一般来说,tcp正常关闭需要四个包。比如a和b关闭连接,a先给b发一个fin,b会进行确认ack,然后b也会发出fin,当a接受到这个fin,并发出最后一个ack后,就会处于time_wait状态。这个时间长短跟操作系统有关,一般会在1-4分钟,也就是两倍的数据包(2msl)最大生存时间。TCP主动关闭方采用TIME_WAIT主要是为了实现终止TCP全双工连接的可靠性及允许老的重复分节在网络中消逝,等过了2msl(大约1~4分钟)后TIME_WAIT就会消失。

所以说,主动发起关闭连接的一方会进入time_wait状态,这个时候,进程所占用的端口号不能被释放。除非在你的程序中用setsockopt设置端口可重用(SOCK_REUSE)的选项,但这不是所有操作系统都支持的,解决TIME_WAIT的办法我个人认为以下两种比较好:

1、禁用LINGER
//Socket API
BOOL bDontLinger=FALSE;
setsockopt(m_socket,SOL_SOCKET,SO_DONTLINGER,(LPCTSTR)&bDontLinger,sizeof(BOOL));
closesocket(s);

//MFC CAsyncSocket或者CSocket
BOOL bDontLinger=FALSE;
m_socket->SetSockOpt(SO_DONTLINGER,(const char *)&bDontLinger,sizeof(bDontLinger),SOL_SOCKET);
m_socket->Close();

2、客户端可以不BIND(),这样,即使断开连接后再次连接,SOCKET将使用不同的端口(1025-5000),等几分钟后,原有的端口就会自动关闭。


网上找到的
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
但是我使用了setsockopt,发现无效,不原因,我用的是api,没有用CSocket

大概如下:
sock = socket(......); //tcp的
long val=1
setsockopt(sock,sol_socket,SO_REUSEADDR,(char*)&val,sizeof(val));
bind(....);

但是发现无效,不知其中奥妙
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
这是我刚才在网上查到的信息


終於在msdn裡找到相關資料解掉了 (msdn的search真的是超難用... >"<).

原因: socket在connect時,Windows會自動找一個port給它bind,這個port的範圍內定為1200-5000,當socket close時,該socket便會進入TIME_WAIT狀態(可在DOS模式下用"netstat -n"查看),必須等待4分鐘(內定值,實測結果似乎應為2分鐘)才能再度使用(Windows 2000會直接拿來再度使用,並不管是否為TIME_WAIT狀態,因此在Windows 2000上測試都沒有問題)

狀況: open/close socket過於頻繁, 便會發生此一錯誤

解決方法:

用regedit找HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters鍵值:

1.調整MaxUserPort參數,以增加可給定port的範圍

型態:DWORD
值域:5000-65534

2.調整TcpTimedWaitDelay參數,以減少TIME_WAIT等待時間

型態:DWORD
值域:30-240,單位為秒

這個問題,應該是要用setsockopt, 去啟用SO_REUSEADDR.

修改TIME_WAIT有可能會造成其他的問題。例如快速Reset後某一方會收到上一次session滯留的packet.
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
嗯,我没看仔细,刚才我又试了一下,

sock.ShutDown(2);
sock.Close();

之后 端口还处于 time_wait 状态
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
大概意思是说bind的错误可能会被推迟,直接调用connect等函数时才发生
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
这是connect的wsaeaddrinuse错误的解释

The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs when executing bind, but could be delayed until this function if the bind was to a partially wild-card address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.
FlyOverSea 2006-11-23
  • 打赏
  • 举报
回复
这是msdn对bind的wsaeaddrinuse的解释

A process on the machine is already bound to the same fully-qualified address and the socket has not been marked to allow address re-use with SO_REUSEADDR. For example, IP address and port are bound in the af_inet case) . (See the SO_REUSEADDR socket option under setsockopt.)

我换过n个域名以(有些直接使用ip),结果都一样
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
会不会是 对方的防火墙防止 dos 攻击?
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
这个我知道 端口不同不会有问题 我只是想知道 为什么端口相同就会出问题?因为我明明close掉了这个socket,为什么还会出现端口被占用的错误

*************************************

端口被占用的话,你 create 就会失败的,根本不可能成功。
ProgrameMan 2006-11-23
  • 打赏
  • 举报
回复
换个端口没有问题 同一端口不行 其实作为客户端连接,可以不需要bind, connect会自动指定不使用的端口, 但当我bind后(即使用Create的参数), 就会出现问题, 我怀疑是端口复用之类的问题 域名换个好几个 都不行

********************************

我认为和端口复用的关系应该不大。我想很可能就是第二个原因引起的
加载更多回复(8)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧