この数時間を調査し、これを理解するためにさまざまなことを試しましたが、私は立ち往生しています。私は、複数のスレッドからアクセスする非同期ソケットを作成しようとしています。同じ時刻に近く送信しようとしているスレッドがいくつかあるまでは正常に動作する傾向があります。 EndReceive()がデータを読み込もうとすると、0バイトが返され、ソケットエラーは "success"になります。私はこれが正常なシャットダウンであったことを意味し、サーバーには送信するデータはもうありませんが、接続するサーバーのタイプはすべてのデータを送信してはいけません。サーバーのタイプではありません。読み取るデータは常にあるべきで、閉じてはいけません。多くのパケットを一度に送信すると、非同期ソケットは常に0バイトを読み取る
いくつかのSystem.Threading.Timersがどこに送信されたのかのスレッドは、スレッドセーフではありません。私もSystem.Timers.Timerで試しましたが、同じ結果でした。私はまた、一度にたくさんのパケットを送信するために1つのスレッドしか使用せず、100msの間スリープしていましたが、同じ結果が得られます。
コードを受信するには、以下のとおりです。送信のために、私はちょうど定期的なブロッキングSendとBeginSendを試しましたが、それは違いはありませんでした。
void Receive()
{
try
{
if (_datacb == null)
_datacb = new AsyncCallback(OnRecvData);
byte[] buffer = new byte[FBufferSize];
FSocket.BeginReceive(buffer, 0, FBufferSize, SocketFlags.None, _datacb, buffer);
}
catch (SocketException ex)
{
OnSocketError(ex);
}
}
void OnRecvData(IAsyncResult ar)
{
try
{
SocketError err;
int bytesRead = FSocket.EndReceive(ar, out err);
if (bytesRead == 0)
{
throw new SocketException();
}
byte[] buffer = ar.AsyncState as byte[];
FReceived.AddBytes(buffer, bytesRead);
ByteBuffer message = FReceived.GetNextMessage();
while (message != null)
{
Process(message);
message = FReceived.GetNextMessage();
}
}
catch (SocketException ex)
{
OnSocketError(ex);
}
Receive();
}
は、私はそれがあまりにも速く送信するためのソケットをシャットダウンしてサーバーであると考えていたが、私は実際に私はVS2008で行われたブロッキングバージョンを持っていると私は1パケットを送信した50種類のタイマーを使用することができました毎秒と私は切断されなかった。私はVS2010でほとんど同じコードを試しましたbytesReadは0でした。私はVS2008でasycソケットコードを試してみました。ちょっと変わったことがあったのですが、VS2008ではまだ私にbytesRead == 0が与えられています。トン私を抜い:
tcpClient = new TcpClient(host, 443);
networkStream = tcpClient.GetStream();
mReader = new BinaryReader(networkStream);
mWriter = new BinaryWriter(networkStream);
receiveMessage = new Thread(new ThreadStart(ReceiveMessages));
receiveMessage.Start();
private void ReceiveMessages()
{
while (true)
{
if ((tcpClient != null) && (tcpClient.Connected))
{
if (tcpClient.Available >= 4)
{
if (!isConnected) isConnected = true;
try
{
ByteBuffer message = new ByteBuffer();
message.AddBytes(mReader.ReadBytes(4));
int mSize = message.ReadInt();
message.AddBytes(mReader.ReadBytes(mSize - 4));
processor.Process(message);
}
catch (Exception ex)
{
Print("Recv Msg: " + ex.Message);
}
}
Thread.Sleep(1);
}
}
を送信:それであまりにも満足していない
mWriter.Write(send);
mWriter.Flush();
を、それがCPUの多くを使用しているため。私は他の方法でこれほど多くのCPUを使わずにこのようなソケットをブロックしようとしましたが、切断する傾向があります。
タイトルに「C#」などのプレフィックスを付けないでください。それがタグのためのものです。 –
これは、例外があってもReceiveを呼び出しているという事実に関連する可能性はありますか?受信は、 "キャッチ"の後ではなく "試行"の最後にあるはずです。IMO –
ブロッキングバージョンは実際にブロックされていますか? IIRCでは、 'tcpClient.Available'は4バイトが利用できるようになるまでブロックしないので、CPUが浪費するsleep(1)ループで待ち時間を浪費します。 –