首页 新闻 会员 周边 捐助

连接socket服务器,提示“通常每个套接字地址(协议/网络地址/端口)只允许使用一次”

0
悬赏园豆:100 [已解决问题] 解决于 2014-10-27 11:23

  大家好,请教一个问题。我现在再写一个cs架构的系统。具体情况是服务器有一个线程监听Socket,一个线程发送。

  监听的线程接收到消息后不会回复,只是把消息存到队列,代码如下:

while (_receiving)
{
byte[] buffer=new byte[1024*1024];
Socket client = _reciever.Accept();
client.Receive(buffer);
IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint;
string senderIP = clientEndPoint.Address.ToString();
int senderPort = clientEndPoint.Port;
this.DLGMSGRecieved(buffer);    //委托,将buffer添加到队列
client.Shutdown(SocketShutdown.Both);
client.Close();
client.Dispose();
}

 

  现在的问题是,我用一个客户端发送消息至该socket服务器,第一次发送没问题,可再次发送会出现:通常每个套接字地址(协议/网络地址/端口)只允许使用一次。 191.1.7.108:55332的错误(55332是服务器socket的端口号)。

  客户端发送代码:

  

int p=0;
do
{
Random r = new Random(5000);
p = r.Next(65535);
} while (!PortIsAvailable(p));//端口号是否被占用

 

IPAddress srcIP = IPAddress.Parse(SourceIP) ;
IPEndPoint srcIPEndPoint = new IPEndPoint(srcIP, p);
IPAddress trgIP = IPAddress.Parse(TargetIP);
IPEndPoint trgIPEndPoint = new IPEndPoint(trgIP, TargetPort);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Blocking = true; //设置阻塞
socket.Bind(srcIPEndPoint);
socket.Connect(trgIPEndPoint);
int sentCount = socket.Send(ByteMessage);
socket.Disconnect(false);
socket.Shutdown(SocketShutdown.Both); //关闭读写
socket.Close();
if (sentCount != ByteMessage.Length)
{
throw (new Exception("消息未发送成功"));
}

 

报错行是:socket.Connect(trgIPEndPoint);

 

请问各位大神这个如何解决?

逆水的主页 逆水 | 初学一级 | 园豆:94
提问于:2014-10-25 16:41
< >
分享
最佳答案
1

是服务端Bind啊,客户端只要connect,系统会使用随机端口。

收获园豆:100
小彬 | 小虾三级 |园豆:947 | 2014-10-26 21:54

真相帝啊

喵喵喵猫 | 园豆:1742 (小虾三级) | 2014-10-27 11:05

哈哈 一句话解决的问题 好像100分给高了点 不过问题解决得了就给你啦

逆水 | 园豆:94 (初学一级) | 2014-10-27 11:22

我想再问一个问题。现在客户端用一个socket发送到服务器,然后服务器需要新建一个Socket client = _reciever.Accept();与之通信。然后通信完了之后是由客户端Shutdown还是由服务器端shutdown。

你看我上面的代码,在发送方和接收方都用了shutdown(),这样是不是不妥。

逆水 | 园豆:94 (初学一级) | 2014-10-27 11:29

@逆水: 都可以shutdown

小彬 | 园豆:947 (小虾三级) | 2016-07-14 13:08

@逆水: 回答的言语越少不正是证明越切中要害么

心影 | 园豆:200 (初学一级) | 2019-08-19 16:06

客户端 也可以指定端口绑定,设置端口复用就行

chdon | 园豆:200 (初学一级) | 2022-05-07 15:30
其他回答(1)
1

服务端用问题,改成类似如下的样子:

Socket client = _reciever.Accept();

while (_receiving)
{
byte[] buffer=new byte[1024*1024];
client.Receive(buffer);
IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint;
string senderIP = clientEndPoint.Address.ToString();
int senderPort = clientEndPoint.Port;
this.DLGMSGRecieved(buffer);    //委托,将buffer添加到队列
 }

client.Shutdown(SocketShutdown.Both);
client.Close();
client.Dispose();

 

你每次都销毁,是会重新分配端口或重新申请端口的。

一般是服务端接收完一批数据后,会自动断开连接,然后转入监听状态等待下次连接,其它客户端就可以连接上来了,如此反复。

空明流光 | 园豆:111 (初学一级) | 2014-10-25 20:39

是客户端的问题,客户端的socket不应该加bind()。不过还是谢谢了

支持(0) 反对(0) 逆水 | 园豆:94 (初学一级) | 2014-10-27 11:22

解释一下,我是想一个client=_reciever.Accept(); 之后接收完数据就把client资源释放掉。然后再接收下一个_reciever.Accept();这样应该要每次都把client shutdown吧。

支持(0) 反对(0) 逆水 | 园豆:94 (初学一级) | 2014-10-27 11:26
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册