接受连接时出现C#SocketException

时间:2015-02-12 20:36:29

标签: c# .net sockets asynchronous

过去一天左右,我一直在努力学习插座。我认为建立一个基本的聊天客户端和服务器是一个好主意,我试图创建一个异步服务器,所以我不需要使用大量的线程等我已经遇到了问题我根本无法修复。当我启动我的服务器时,它会通过所有ok并等待它需要等待连接的点。然后我启动了我的临时客户'这只是简单地发送一个字符串,我的服务器崩溃了SocketException消息

  

附加信息:由于套接字未连接而且(使用sendto调用在数据报套接字上发送时)未提供发送或接收数据的请求,因此未提供地址

当我的套接字必须首先接受连接时,我看不到它是如何连接的。我一直在使用本教程(https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx)作为指南,看了我的代码和教程,但仍然不了解我做错了什么,有人可以帮助我吗?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Chat_Application
{
    class Server
    {
        private Socket serverSocket = null;
        private volatile ArrayList connections = null; // will hold all client sockets
        private const int port = 1090;
        private IPAddress ipAddress = null;
        private IPEndPoint ipEndPoint = null;
        private Thread listenThread = null; // seperate thread to run the server 
        private ManualResetEvent allDone = null;

        public Server()
        {
            this.serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.connections = new ArrayList();
            ipAddress = IPAddress.Parse(GetLocalIPv4(NetworkInterfaceType.Ethernet));
            ipEndPoint = new IPEndPoint(ipAddress, port);
            listenThread = new Thread(StartListen);
            allDone = new ManualResetEvent(false);
        }

        public void Start()
        {
            listenThread.Start();
        }

        public void StartListen()
        {
            this.serverSocket.Bind(ipEndPoint);
            this.serverSocket.Listen(20);
            Program.mainWin.console.Text += "\n<INFO> Socket bound, listening for connections...";

            while (true)
            {
                allDone.Reset();
                serverSocket.BeginAccept(new AsyncCallback(AcceptConnectionAsync), serverSocket);
                Program.mainWin.console.Text += "\n<INFO> Conncetion accepted...";
                allDone.WaitOne();

            }
        }

        public void AcceptConnectionAsync(IAsyncResult AR)
        {
            Byte[] bufferBytes = new byte[1024]; 
            allDone.Set();
            Socket client = (Socket) AR.AsyncState;
            int x = client.Receive(bufferBytes);
            Program.mainWin.console.Text += System.Text.Encoding.Default.GetString(bufferBytes);

        }

        public string GetLocalIPv4(NetworkInterfaceType _type)
        {
            string output = "";
            foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
                {
                    foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
                    {
                        if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                        {
                            output = ip.Address.ToString();
                        }
                    }
                }
            }
            return output;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您永远不会调用EndAccept(来自您关联的示例):

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar); // This right here

ar.AsyncState中的套接字是监听套接字,而不是连接的客户端。 AsyncState是一个任意对象,可用于将信息传递给回调方法(AcceptConnectionAsync)。在这种情况下,您传递的是serverSocket(下面的第二个参数):

serverSocket.BeginAccept(new AsyncCallback(AcceptConnectionAsync), serverSocket);

当您在侦听套接字上调用EndAccept时,您将获得一个 new Socket实例,该实例是与客户端的特定连接 - 您的侦听器套接字将启动异步请求接受whileStartListen循环中的其他连接。 EndAccept返回的套接字处于连接状态,并准备根据此特定回调调用与另一个端点进行通信(因此,需要提供IAsyncResult作为参数)。

这被称为异步编程模型MSDN has some great information就此而言(像往常一样)。