您的位置:首页 > 编程语言 > C#

[2015/11/17] -C#- 服务器调试 SocketException 使用了与请求的协议不兼容的地址

2015-11-17 20:40 751 查看

报错内容:

“_listener.EnableBroadcast”引发了“System.Net.Sockets.SocketException”类型的异常

“_listener.MulticastLoopback”引发了“System.Net.Sockets.SocketException”类型的异常


当然这个到最后调试成功了还是没有避免这两个异常。。

最关键的是这个,被System.dll抛出的SocketException使用了与请求的协议不兼容的地址。

原来的代码:

_server = new NetTCPServer();
_server.CreateTcpServer("127.0.0.1", 10001))

Console.WriteLine("启动聊天服务器!");


这是被调用的代码:

public bool CreateTcpServer( string ip, int listenPort )
{
_port = listenPort;
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

foreach (IPAddress address in Dns.GetHostEntry(ip).AddressList)
{
try
{
IPAddress hostIP = address;
IPEndPoint ipe = new IPEndPoint(address, _port);

//********此行报错*******
_listener.Bind(ipe);
_listener.Listen(_maxConnections);
_listener.BeginAccept(new System.AsyncCallback(ListenTcpClient), _listener);

break;

}
catch (System.Exception)
{
return false;
}
}

return true;
}
为什么报错呢,我逐过程跟踪了一下,具体底层的不懂,就说说表象。

代码有两个问题:

1)CreateTcpServer这个函数返回的是一个bool值。源代码连true/false都不判断就直接输出启动聊天服务器了,我实在是给跪。

怪不得我在Unity里面怎么样都没法连接上服务器。

2)事实上Dns.GetHostEntry(ip).AddressList会返回一个数组,里面有两个值,如果你联网了,这两个值都是乱码;

如果没联网,其中第二个是正确的,然而用第二个正确的也会报出SocketException这个异常。这说明Dns.GetHostEntry(ip).AddressList对于获取套接字来说,对于这个比较简单的案例来说——是多余的。

修改方案:

1)判断一下CreateTcpServer函数返回值。

_server = new NetTCPServer();
if (_server.CreateTcpServer("127.0.0.1", 10001))
{
Console.WriteLine("启动聊天服务器!");
}
else {
Console.WriteLine("启动聊天服务器失败!");
}


2)最核心的解决方案啦。

public bool CreateTcpServer(string ip, int listenPort)
{
_port = listenPort;
_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

try
{
IPAddress address = IPAddress.Parse(ip);

//创建网络节点对象 包含 ip和port
IPEndPoint endpoint = new IPEndPoint(address, _port);

//将 监听套接字  绑定到 对应的IP和端口
_listener.Bind(endpoint);

//设置监听队列为最大连接数量
_listener.Listen(_maxConnections);

//等待客户端的连接
_listener.BeginAccept(new System.AsyncCallback(ListenTcpClient),
_listener);
} catch (System.Exception e)
{
return false;
}
return true;
}
OK搞定~

最终Unity和控制台输出的结果是这样的:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: