2017-07-04 12 views
0

私は非同期チャットサーバーを構築しようとしていると、これは私がこれまでに得たものである:C#非同期チャットサーバー

サーバー

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 

public class StateObject 
{ 
    public Socket workSocket = null; 
    public const int BufferSize = 1024; 
    public byte[] buffer = new byte[BufferSize]; 
    public StringBuilder sb = new StringBuilder(); 
} 

public class AsynchronousSocketListener 
{ 
public static ManualResetEvent allDone = new ManualResetEvent(false); 

public AsynchronousSocketListener() 
{ 
} 

public static void StartListening() 
{ 
    byte[] bytes = new Byte[1024]; 
    IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); 
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); 
    Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); 

    try 
    { 
     listener.Bind(localEndPoint); 
     listener.Listen(100); 

     while (true) 
     { 
      allDone.Reset(); 
      Console.WriteLine("Waiting for a connection..."); 
      listener.BeginAccept(new AsyncCallback(AcceptCallback),listener); 
      allDone.WaitOne(); 
     } 

    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 

    Console.WriteLine("\nPress ENTER to continue..."); 
    Console.Read(); 

} 

public static void AcceptCallback(IAsyncResult ar) 
{ 
    allDone.Set(); 
    Socket listener = (Socket)ar.AsyncState; 
    Socket handler = listener.EndAccept(ar); 
    StateObject state = new StateObject(); 
    state.workSocket = handler; 
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state); 
} 

public static void ReadCallback(IAsyncResult ar) 
{ 
    String content = String.Empty; 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket handler = state.workSocket; 
    int bytesRead = handler.EndReceive(ar); 

    if (bytesRead > 0) 
    { 
     state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); 
     content = state.sb.ToString(); 
     if (content.IndexOf("<EOF>") > -1) 
     { 
      Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",content.Length, content); 
      Send(handler, content); 
     } 
     else 
     { 
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state); 
     } 
    } 
} 

private static void Send(Socket handler, String data) 
{ 
    byte[] byteData = Encoding.ASCII.GetBytes(data); 
    handler.BeginSend(byteData, 0, byteData.Length, 0,new AsyncCallback(SendCallback), handler); 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     Socket handler = (Socket)ar.AsyncState; 
     int bytesSent = handler.EndSend(ar); 
     Console.WriteLine("Sent {0} bytes to client.", bytesSent); 
     handler.Shutdown(SocketShutdown.Both); 
     handler.Close(); 

    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

public static int Main(String[] args) 
{ 
    StartListening(); 
    return 0; 
} 
} 

クライアント

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using System.Text; 

public class StateObject 
{ 
    public Socket workSocket = null; 
    public const int BufferSize = 256; 
    public byte[] buffer = new byte[BufferSize]; 
    public StringBuilder sb = new StringBuilder(); 
} 

public class AsynchronousClient 
{ 
    private const int port = 11000; 
    private static ManualResetEvent connectDone =new ManualResetEvent(false); 
    private static ManualResetEvent sendDone =new ManualResetEvent(false); 
    private static ManualResetEvent receiveDone =new ManualResetEvent(false); 
    private static String response = String.Empty; 
    static String username = ""; 
    static int a = 1; 

private static void StartClient() 
{ 
    try 
    { 
     Console.WriteLine("Username: "); 
     username = Console.ReadLine(); 

     while (a == 1) 
     { 
      IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); 
      IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); 
      Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); 
      connectDone.WaitOne(); 

      Console.WriteLine("Receiver: "); 
      String receiver = Console.ReadLine(); 
      Console.WriteLine("Message: "); 
      String message = Console.ReadLine(); 

      String Message = username + "[" + receiver + "[" + message + "<EOF>"; 
      Send(client, Message); 
      sendDone.WaitOne(); 
      Receive(client); 
      receiveDone.WaitOne(); 
      Console.WriteLine("Response received : {0}", response); 
     } 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

private static void ConnectCallback(IAsyncResult ar) 
{ 
    try 
    { 
     Socket client = (Socket)ar.AsyncState; 
     client.EndConnect(ar); 
     connectDone.Set(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

private static void Receive(Socket client) 
{ 
    try 
    { 
     StateObject state = new StateObject(); 
     state.workSocket = client; 
     client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReceiveCallback), state); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

private static void ReceiveCallback(IAsyncResult ar) 
{ 
    try 
    { 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket client = state.workSocket; 
     int bytesRead = client.EndReceive(ar); 

     if (bytesRead > 0) 
     { 
      state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); 
      client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReceiveCallback), state); 
     } 
     else 
     { 
      if (state.sb.Length > 1) 
      { 
       response = state.sb.ToString(); 
      } 
      receiveDone.Set(); 
     } 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

private static void Send(Socket client, String data) 
{ 
    byte[] byteData = Encoding.ASCII.GetBytes(data); 
    client.BeginSend(byteData, 0, byteData.Length, 0,new AsyncCallback(SendCallback), client); 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     Socket client = (Socket)ar.AsyncState; 
     int bytesSent = client.EndSend(ar); 
     Console.WriteLine("Sent {0} bytes to server.", bytesSent); 
     sendDone.Set(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

public static int Main(String[] args) 
{ 
    StartClient(); 
    return 0; 
} 
} 

私ができますよサーバーにメッセージを送信して回答を返すことができますが、毎回接続が切断され、再接続する必要があります。このように、メッセージを送信した後にメッセージを受け取ることができません。私はクライアントをサーバーに接続し、両方の方法でメッセージを送信し、接続を手動で停止する方法を探しています。 さらに、あるクライアントから別のクライアントにメッセージを送信し、そのサーバーに接続しているすべてのクライアントにメッセージを送信する方法を探しています。

私が持っているもう1つの質問は、複数のポートをセットアップして、サーバーがすべてのポートを受信できるようにする方法です。私は、ログイン用に1つのポートを開き、メッセージ用に1つのポートを開こうとしていました。

+0

handler.ShutDown(...)を実行すると、サーバーのSendCallbackでソケットを閉じます。 and handler.Close();私は、接続が終了するまでソケットを開いたままにする必要があると思います。 https://msdn.microsoft.com/en-us/library/wahsac9k(v=vs.110).aspx – m4ttsson

答えて

0

しかし

ため、接続は毎回切断されて、あなたの明示的にあなたが代わりに

+0

代わりにhandler.BeginReceiveを呼び出すと、サーバーからの応答が得られません。 –

1

私が探しているhandler.BeginReceiveを呼び出すことができますSendCallback

Socket handler = (Socket) ar.AsyncState; 
handler.Shutdown(SocketShutdown.Both); 
handler.Close(); 

でそれを閉じます私のクライアントをサーバーに接続する方法、両方の方法でメッセージを送信する方法、cを停止する方法接続マニュアル。

接続を切断するには、ループの後に切断呼び出しを追加することができます(client.Disconnect(false))。いくつかの終了条件の後、単にループを終了します。

usingステートメントでクライアントを作成することをお勧めします。この方法で自動的に処理されます。

+0

usingステートメントの例を挙げてください。 –

+0

こちらをご覧ください:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement –