Во-первых, я хочу сказать, что этот код с сервером/клиентом отлично работает на моем ПК (и клиент, и сервер работают на одном ПК).
Проблема начинается, когда я размещаю сервер на выделенном сервере. Во второй раз, когда я пытаюсь отправить или получить с помощью клиента, клиенту потребуется МНОГО ВРЕМЕНИ для завершения операции (речь идет о получении 1 байта данных, который занимает более 1 часа!)
** Я могу избежать этой проблемы, просто отключая и снова подключая сокет после каждой команды отправки/получения.
Я не понимаю, почему это занимает так много времени, если я буду выполнять более 1 операции отправки/получения в рамках одного и того же сеанса подключения.
Вот пример:
для подключения сервера:
RC_Server = new SocketConnection_Client(RC_IpEndPoint);
теперь клиент подключен к серверу, и я могу нормально отправлять/получать.
В первый раз, когда я пытаюсь отправить или получить, он работает отлично и быстро (независимо от длины буфера).
RC_Server.sendCompleted = false;
RC_Server.Send(buffer); //in this case buffer size is 1024
while (!RC_Server.sendCompleted) { } //here thread is waiting for the send to complete
теперь, если я хочу начать сеанс приема с сервером
RC_Server.receiveCompleted = false;
RC_Server.Receive(buffer.Length); //in this case byffer needs to get 4 bytes from server
while (!RC_Server.receiveCompleted) { } // <<- Here it will take VERY long time for the operation to complete
buffer = RC_Server.buffer;
Вторая операция получения никогда не достигает события socket_receiveCompleted_Completed.
Но... если я закрою соединение с сервером после первого сеанса отправки/получения, а затем открою новое соединение с сервером, а затем выполню следующий сеанс отправки/получения, тогда все будет работать отлично. (и дублировать этот метод несколько раз для нескольких отправок/получений)
И снова проблема не возникает на моей рабочей станции (если я запускаю сервер и клиент на одном ПК). Это происходит только в том случае, если я размещаю сервер на удаленном хосте.
Вот часть моего класса сокетов:
class SocketConnection_Client
{
public string errorMsg = string.Empty;
public bool receiveCompleted = false;
public bool sendCompleted = false;
int bytesReceived = 0;
public byte[] buffer;
Socket socket;
public SocketConnection_Client(IPEndPoint ipEP)
{
socket = new Socket(ipEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(ipEP);
}
catch (Exception ex)
{
errorMsg = ex.Message;
socket.Dispose();
socket = null;
}
}
public void Send(byte[] sBuffer)
{
buffer = null;
if (socket == null)
{
sendCompleted = true;
return;
}
sendCompleted = false;
SocketAsyncEventArgs socket_sendCompleted = new SocketAsyncEventArgs();
socket_sendCompleted.SetBuffer(sBuffer, 0, sBuffer.Length);
socket_sendCompleted.Completed += socket_sendCompleted_Completed;
socket.SendAsync(socket_sendCompleted);
}
void socket_sendCompleted_Completed(object sender, SocketAsyncEventArgs e)
{
sendCompleted = true;
}
public void Receive(int bLength)
{
bytesReceived = 0;
buffer = null;
if (socket == null)
{
receiveCompleted = true;
return;
}
receiveCompleted = false;
buffer = new byte[bLength];
SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs();
socket_receiveCompleted.SetBuffer(buffer, 0, buffer.Length);
socket_receiveCompleted.Completed += socket_receiveCompleted_Completed;
socket.ReceiveAsync(socket_receiveCompleted);
}
private void Receive_Continue()
{
SocketAsyncEventArgs socket_receiveCompleted = new SocketAsyncEventArgs();
socket_receiveCompleted.SetBuffer(buffer, bytesReceived, buffer.Length - bytesReceived);
socket_receiveCompleted.Completed += socket_receiveCompleted_Completed;
socket.ReceiveAsync(socket_receiveCompleted);
}
void socket_receiveCompleted_Completed(object sender, SocketAsyncEventArgs e)
{
bytesReceived += e.BytesTransferred;
if (e.BytesTransferred == 0 && bytesReceived == 0)
{
socket.Dispose();
socket = null;
receiveCompleted = true;
throw new Exception("Server Disconnected");
}
else if (bytesReceived != buffer.Length)
Receive_Continue();
else
receiveCompleted = true;
}
}
Ценится. Спасибо.