2015-02-12 2 views
0

Я пытался узнать о сокетах за последний день или около того. Я подумал, что было бы неплохо сделать базовый чат-клиент и сервер, чтобы учиться, я попытался создать асинхронный сервер, поэтому мне не нужно использовать множество потоков и т. Д., И я столкнулся с проблемой, которую я просто могу Исправить. Когда я запускаю свой сервер, он проходит через все нормально и ждет там, где ему нужно дождаться соединения. Я затем запустить свой импровизированный «клиент», который просто посылает строку сейчас и мой сервер падает с SocketException с сообщениемC# 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

Вы никогда не называя 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 на сокете, вы получаете новогоSocket экземпляра, который является специфической связью с клиентом - - ваш разъем-слушатель начнет асинхронный запрос, чтобы принять другое соединение в вашем while в StartListen. Сокет, возвращаемый EndAccept, находится в состоянии соединения и готов к общению с другой конечной точкой на основе этого конкретного вызова обратного вызова (следовательно, требование предоставить IAsyncResult в качестве аргумента).

Это асинхронная модель программирования . MSDN has some great information на это (как обычно).

+0

Блестящий! Не знаю, как я это забыл! Просто дай мне понять это правильно. Объект-слушатель по существу является копией сокета, который я назвал .BeginAccept() на более раннем (serverSocket в моем примере), поэтому, установив новый объект в listener.EndAccept() Я захватываю сокет от serverSocket? Также почему мне нужно передать «AR» в конец? – Sicarius

+1

Отредактировал мой ответ, чтобы добавить дополнительную информацию для вас :) – wgraham

+0

Ты легенда, приветственный помощник. – Sicarius

Смежные вопросы