2015-09-22 3 views
1

Я пытаюсь создать простую клиент-серверную программу, которая поможет в обучении сетевому программированию. Я собираюсь построить онлайн-шахматную игру, но прямо сейчас я просто пытаюсь сделать основы. Я собрал код из онлайн-источников (MSDN), и я думал, что все будет работать нормально. Вот сценарий:Клиент не может читать более одного сообщения с сервера (C#)

Клиент посылает тестовое сообщение на сервер
Сервер ответа вторит
Клиент читает ответ и отображает тестовое сообщение.
Клиент посылает новое сообщение на сервер
ответ вторит
клиент отображает тест сообщение Сервер

Правильный выход должен быть следующим:

Клиент посылает тестовое сообщение к серверу
Ответ сервера echos
Клиент считывает ответ и отображает тестовое сообщение.
Клиент посылает нового сообщение к серверу
ответа сервер вторит
клиент отображает нового сообщение

Любая помощь приветствуется!

Вот соответствующая часть клиента:

private void OnlineButton_Click(object sender, EventArgs e) 
    { 
     // Connect to a remote device. 
     try 
     { 
      // Create a TCP/IP socket. 
      client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

      // Connect to the remote endpoint. 
      client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); 
      connectDone.WaitOne(); 

      // Send test data to the remote device. 
      Send(client, "This is a test<EOF>"); 
      sendDone.WaitOne(); 

      // Receive the response from the remote device. 
      Receive(client); 
      receiveDone.WaitOne(); 

      msg("Response received: " + response); 

     } 
     catch (Exception ex) 
     { 
      msg(ex.ToString()); 
     } 
     msg("Client started, connected to: " + client.RemoteEndPoint.ToString()); 
     sessionHandler(2); 
    } 

    public void msg(string mesg) 
    { 
     ServerMessages.Text = ServerMessages.Text + Environment.NewLine + " >> " + mesg; 
    } 

    public void sessionHandler(Int32 mode) 
    { 
     switch (mode) 
     { 
      case 1: 
       msg("Starting AI program..."); 
       break; 
      case 2: 
       // Create a TCP/IP socket. 
       client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

       // Connect to the remote endpoint. 
       client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); 
       connectDone.WaitOne(); 

       Send(client, "Play Online<EOF>"); 
       sendDone.WaitOne(); 

       Receive(client); 
       receiveDone.WaitOne(); 

       msg("Response received: " + response); 

       msg("Pairing with another player..."); 
       break; 
      case 3: 
       msg("Replaying selected game..."); 
       break; 
      default: 
       msg("Error handling request..."); 
       break; 
     } 
    } 

Здесь сервер:

// State object for reading client data asynchronously 
public class StateObject 
{ 
    // Client socket. 
    public Socket workSocket = null; 
    // Size of receive buffer. 
    public const int BufferSize = 1024; 
    // Receive buffer. 
    public byte[] buffer = new byte[BufferSize]; 
    // Received data string. 
    public StringBuilder sb = new StringBuilder(); 
} 

public class AsynchronousSocketListener 
{ 
// Thread signal. 
public static ManualResetEvent allDone = new ManualResetEvent(false); 

public AsynchronousSocketListener() 
{ 
} 

public static void StartListening() 
{ 
    // Data buffer for incoming data. 
    byte[] bytes = new Byte[1024]; 

    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 8888); 

    // Create a TCP/IP socket. 
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

    // Bind the socket to the local endpoint and listen for incoming connections. 
    try 
    { 
     listener.Bind(localEndPoint); 
     listener.Listen(100); 

     while (true) 
     { 
      // Set the event to nonsignaled state. 
      allDone.Reset(); 

      // Start an asynchronous socket to listen for connections. 
      Console.WriteLine("Waiting for a connection..."); 
      listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); 

      // Wait until a connection is made before continuing. 
      allDone.WaitOne(); 
     } 

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

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

} 

public static void AcceptCallback(IAsyncResult ar) 
{ 
    // Signal the main thread to continue. 
    allDone.Set(); 

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

    // Create the state object. 
    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; 

    // Retrieve the state object and the handler socket 
    // from the asynchronous state object. 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket handler = state.workSocket; 

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar); 

    if (bytesRead > 0) 
    { 
     // There might be more data, so store the data received so far. 
     state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); 

     // Check for end-of-file tag. If it is not there, read 
     // more data. 
     content = state.sb.ToString(); 
     if (content.IndexOf("<EOF>") > -1) 
     { 
      // All the data has been read from the 
      // client. Display it on the console. 
      Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content); 
      // Echo the data back to the client. 
      Send(handler, content); 
     } 
     else 
     { 
      // Not all data received. Get more. 
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); 
     } 
    } 
} 

private static void Send(Socket handler, String data) 
{ 
    // Convert the string data to byte data using ASCII encoding. 
    byte[] byteData = Encoding.ASCII.GetBytes(data); 

    // Begin sending the data to the remote device. 
    handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     // Retrieve the socket from the state object. 
     Socket handler = (Socket)ar.AsyncState; 

     // Complete sending the data to the remote device. 
     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; 
} 

}

РЕДАКТИРОВАТЬ:

Разъяснение по проблеме:

Клиент только, кажется, читает первый ответ, который дает сервер. Пример:

Клиент посылает "Hello"
эхо сервера "HELLO"
клиент отображает "Hello"
Клиент посылает "Мир"
сервер вторит "Мир"
клиент отображает "Hello" (это должны быть World)

+0

Просьба указать, что не работает должным образом. Также: ваш «сценарий» и «вывод должны быть» содержат точно такой же контент. Это верно? – BatteryBackupUnit

+0

Извините, я обновил вопрос, чтобы уточнить проблему. – user2069621

ответ

0

я понял проблему. Мне понадобился Thread.sleep (3) после каждого получения.Исправлено: