Исключение размера буфера TCPClient - PullRequest
0 голосов
/ 26 апреля 2018

Я использую простое клиентское приложение TCP для отправки запроса на сервер.Это код клиента, который отправляет клиентское сообщение на сервер.Сервер отправляет ответ, но иногда ответ представляет собой пустую строку.

Я поймал точку останова, когда это произошло, и увидел, что, когда я наведу курсор мыши на client.ReceiveBufferSize, она показывает исключение ObjectDisposedException.

Вот код:

private string SendClientMsg(string textToSend, string handID)
{ 
    TcpClient client = new TcpClient(serverIP, port);
    NetworkStream nwStream = client.GetStream();
    //---create a TCPClient object at the IP and port no.---
    byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(textToSend);

    //---send the text---
    nwStream.Write(bytesToSend, 0, bytesToSend.Length);

    //---read back the text---
    byte[] bytesToRead = new byte[client.ReceiveBufferSize];
    int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
    string response = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
    client.Close();
    return response;
    }
 }

Этот метод принадлежит классу.Несколько потоков используют этот метод для отправки запросов на сервер.Может быть, один поток открывает соединение и начинает отправку, но в то же время другой поток закрывает соединение, используя client.Close()

Я не уверен, что все потоки используют один и тот же объект TcpClient.(Это одноэлементный объект, поэтому он используется всеми потоками?).Если это так, мне придется установить блокировку, чтобы убедиться, что несколько потоков не обращаются к этому методу одновременно.

1 Ответ

0 голосов
/ 26 апреля 2018

Каждый раз, когда вызывается этот метод, создается новый экземпляр TcpClient:

TcpClient client = new TcpClient(serverIP, port);

Только вызывающий поток имеет доступ к этому экземпляру, так что это не проблема.

Проблема в том, что вы предполагаете, что вы получите полный ответ
в одном чтении:

int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);

От MSDN :

Общее количество байтов, считанных в буфер.Это может быть меньше количества запрошенных байтов, если такое количество байтов в данный момент недоступно, или ноль (0), если достигнут конец потока.

Требуется время, чтобы серверответить, и ответ
будет отправлен по сети.Когда вы вызываете Read, весь ответ может быть или может быть недоступен, поэтому вам нужно читать в цикле, пока не будет достигнут конец потока.

var responseBuffer = new byte[client.ReceiveBufferSize];
var bytesRead = 0;
int read;
do
{
   read = nwStream.Read(responseBuffer, 0, client.ReceiveBufferSize);
} while (read > 0)

Это предполагает, что сервер закрываетПравильно установить соединение после обработки запроса.
Если соединение остается открытым, вам придется использовать другой метод
, чтобы определить, что вы получили полный ответ на запрос.

...