2017-07-04 146 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; 
} 
} 

我能发送消息到服务器并取回答案,但每次都会断开连接,我必须重新连接它,并且像这样,在发送消息后我将无法收到消息。我正在寻找一种方法将我的客户端连接到服务器,以两种方式发送消息并停止手动连接。 此外,我正在寻找一种方法将消息从一个客户端发送到另一个客户端,并向所有连接到服务器的客户端发送消息。

另一个问题我有,如何设置多个端口,让服务器监听所有端口?我想打开一个登录端口和一个消息端口。

+0

当您执行handler.ShutDown(...)时,关闭您在服务器上的SendCallback中的套接字。和handler.Close();我认为你需要打开套接字直到连接被你终止。 https://msdn.microsoft.com/en-us/library/wahsac9k(v=vs.110).aspx – m4ttsson

回答

0

但连接被切断每次

,因为你明确地关闭它在SendCallback

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

你可以叫handler.BeginReceive代替

+0

如果我调用handler.BeginReceive,我不会收到来自服务器的响应。 –

1

我正在寻找一个将客户端连接到服务器的方式,以两种方式发送消息并停止c联系手册。

关闭连接可以通过在循环后添加断开连接呼叫来完成:client.Disconnect(false)。在一些退出条件之后,您只需退出循环。

尽管在using声明中创建客户端会更好,但这样它将自动处理。

+0

你能举一个使用语句的例子吗? –

+0

看看这里:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement –