2015-06-07 3 views
-1

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

код Упрощенный сервер:

public class XMLServer 
{ 
    public void start() 
    { 
     server = new TcpListener(_serverIP, _serverPort); 

     try 
     { 
      server.Start(); 
     } 
     catch (SocketException socketError) 
     { 
      Console.WriteLine(socketError.Message); 
     } 
    } 
    public void listen() 
    { 
     try 
     { 
      client = server.AcceptTcpClient(); 

      while (true) 
      { 
       receiveFromClient(); 
      } 
     } 
     catch (SocketException error) 
     { 
      Console.WriteLine(error.Message); 
     } 
    } 

    public void receiveFromClient() 
    { 
     byte[] bytes = new byte[client.ReceiveBufferSize]; 
     byte[] send; 
     int readed; 

     stream = client.GetStream(); 
     readed = stream.Read(bytes, 0, client.ReceiveBufferSize); 

     if (readed > 0) 
     { 
      string[] request = Encoding.UTF8.GetString(bytes).Split(':'); 

      Console.WriteLine(request[0]); 
      switch (request[0]) 
      { 
       case "getFileList": 
        send = encode(XMLFile.getFileList()); 

        if (stream.CanWrite) 
        { 
         stream.Write(send, 0, send.Length); 
        } 
        break; 
       case "getFile": 
        send = encode(XMLFile.getFile(request[1])); 

        if (stream.CanWrite) 
        { 
         stream.Write(send, 0, send.Length); 
         stream.Flush(); 
        } 
        break; 
      } 
     } 
    } 
} 

Использование кода сервера:

XMLServer server = new XMLServer("10.0.0.5", "7777"); 
server.start(); 

while (true) 
{ 
    server.listen(); 
} 

код клиента:

public partial class Client : Form 
{ 
    private TcpClient client; 
    private NetworkStream stream; 

    public Client(TcpClient parentClient) 
    { 
     InitializeComponent(); 
     client = parentClient; 
     getFileList(); 
    } 

    private void getFileList() 
    { 
     byte[] fileList = Encoding.UTF8.GetBytes("getFileList:null"); 
     byte[] fileListResponse; 
     string[] files; 
     int Y = 30; 

     stream = client.GetStream(); 
     stream.Write(fileList, 0, fileList.Length); 

     fileListResponse = new byte[client.ReceiveBufferSize]; 
     stream.Read(fileListResponse, 0, client.ReceiveBufferSize); 
     files = Encoding.UTF8.GetString(fileListResponse).Split(';'); 

     foreach (string file in files) 
     { 
      RadioButton radioButton = new RadioButton(); 
      radioButton.Text = file; 
      radioButton.Location = new Point(10, Y); 

      groupBoxFiles.Controls.Add(radioButton); 
      Y += 30; 
     } 
    } 

    private void buttonOpenFile_Click(object sender, EventArgs e) 
    { 
     String fileName = groupBoxFiles.Controls.OfType<RadioButton>().FirstOrDefault(x => x.Checked).Text; 
     byte[] getFile = Encoding.UTF8.GetBytes("getFile:" + fileName); 
     byte[] getFileResponse; 
     string fileContent; 

     stream = client.GetStream(); 
     stream.Write(getFile, 0, getFile.Length); 

     getFileResponse = new byte[client.ReceiveBufferSize]; 
     stream.Read(getFileResponse, 0, client.ReceiveBufferSize); 
     fileContent = Encoding.UTF8.GetString(getFileResponse); 

     textBoxEditor.Enabled = true; 
     textBoxEditor.Text = fileContent; 
    } 
} 

Сначала я звоню XMLFile.getFileList, и я хорошо работаю. Затем я хочу позвонить XMLFile.getFile, после чего приложение остановится.

Что не так?

+0

Можете ли вы также опубликовать (по крайней мере, соответствующую часть) код клиента? – CristiFati

+0

Код клиента добавлен. – czeski

+0

Еще один вопрос: как 'XMLFile.getFileList()' возвращает файлы (в какой форме)? Другими словами, вы можете опубликовать имя файла - метку «RadioButton», которую вы выбрали, чтобы получить ее содержимое? – CristiFati

ответ

0

Трудно сказать одну причину, но по крайней мере существует концептуальная проблема: результат вызова Stream.Read Method, фактическое количество прочитанных байтов, игнорируется.

передачи/приема функции сокета не гарантирует, которое будет отправлено все данные, при условии /, полученные на один вызов. Функции возвращают действительное количество отправленных/полученных байтов.

- TCP/IP client-server application: exchange with string messages, Sergey Brunov.

Кроме того, обратите внимание:

Вы должны закрыть NetworkStream, когда вы через передачи и приема данных. Закрытие TcpClient не освобождает NetworkStream.

- TcpClient.GetStream Method, MSDN.

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