关闭

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

标签: 服务器调试异常serverC#
1133人阅读 评论(0) 收藏 举报
分类:

报错内容:

“_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和控制台输出的结果是这样的:


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:16531次
    • 积分:473
    • 等级:
    • 排名:千里之外
    • 原创:30篇
    • 转载:4篇
    • 译文:0篇
    • 评论:7条
    文章分类