Первый
Вы не используете асинхронные сокеты, в противном случае вы бы либо вызывали Socket.BeginSend или Socket.SendAsync . Вызов Socket.Send
не является асинхронным, фактически это ОЧЕНЬ синхронно!
Второй
Я не вижу, что метод invoke имеет отношение к тому, что вы тоже не можете отправлять данные ... вы сейчас описываете проблему передачи данных через сокет, но вы даете нам пример кода, который показывает вам вызывающий вызов в главном потоке, который запускает new Thread
и каким-то образом заставляет сокет идти AWOL !
Третий
Пожалуйста, предоставьте пример кода, совместимого с sscce , который мы можем использовать, чтобы воспроизвести вашу проблему (как минимум), или предоставить более подходящий код в отношении:
- Как вы отправляете данные на сервер.
- Что делает код, вызванный в новом потоке (т. Е. Делает ли он что-нибудь с сокетом?)
- Что вы делаете на стороне сервера для получения данных.
Обновление:
Вот моя версия ... Я начинаю с создания метода BeginReceive
. Он устанавливает получение сокета и вызывает метод BeginReceive
для сокета:
private void BeginReceive()
{
if ( _clientState == EClientState.Receiving)
{
if (_asyncTask.BytesReceived != 0 && _asyncTask.TotalBytesReceived <= _maxPageSize)
{
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.SetBuffer(_asyncTask.ReceiveBuffer, 0, _asyncTask.ReceiveBuffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(ReceiveCallback);
e.UserToken = _asyncTask.Host;
bool comletedAsync = false;
try
{
comletedAsync = _socket.ReceiveAsync(e);
}
catch (SocketException se)
{
Console.WriteLine("Error receiving data from: " + _asyncTask.Host);
Console.WriteLine("SocketException: {0} Error Code: {1}", se.Message, se.NativeErrorCode);
ChangeState(EClientState.Failed);
}
if (!comletedAsync)
{
// The call completed synchronously so invoke the callback ourselves
ReceiveCallback(this, e);
}
}
else
{
//Console.WriteLine("Num bytes received: " + _asyncTask.TotalBytesReceived);
ChangeState(EClientState.ReceiveDone);
}
}
}
Это обратный вызов приема (обратите внимание, что он снова вызывает BeginReceive
):
private void ReceiveCallback(object sender, SocketAsyncEventArgs args)
{
lock (_sync) // re-entrant lock
{
// Fast fail: should not be receiving data if the client
// is not in a receiving state.
if (_clientState == EClientState.Receiving)
{
String host = (String)args.UserToken;
if (_asyncTask.Host == host && args.SocketError == SocketError.Success)
{
try
{
Encoding encoding = Encoding.ASCII;
_asyncTask.BytesReceived = args.BytesTransferred;
_asyncTask.TotalBytesReceived += _asyncTask.BytesReceived;
_asyncTask.DocSource += encoding.GetString(_asyncTask.ReceiveBuffer, 0, _asyncTask.BytesReceived);
BeginReceive(); // <---- THIS IS WHAT YOU'RE MISSING
}
catch (SocketException e)
{
Console.WriteLine("Error receiving data from: " + host);
Console.WriteLine("SocketException: {0} Error Code: {1}", e.Message, e.NativeErrorCode);
ChangeState(EClientState.Failed);
}
}
else if (_asyncTask.Host != host)
{
Console.WriteLine("Warning: received a callback for {0}, but the client is currently working on {1}.",
host, _asyncTask.Host);
}
else
{
Console.WriteLine("Socket Error: {0} when receiving from {1}",
args.SocketError,
_asyncTask.Host);
ChangeState(EClientState.Failed);
}
}
}
}
Другими словами, вы называете это:
gelenAday.adaySoket.BeginReceive(tampon, 0, tampon.Length, SocketFlags.None, new AsyncCallback(mesajGeldi), gelenAday);
В mesajGeldi
вы должны вызывать функцию, которая вызывает вышеуказанный метод. Вы должны изолировать этот вызов в методе, который заботится только о запуске begin / receive (как показано в моем примере), и он ничего не делает с установлением сокетного соединения.