[英]Asynchronous TCPClient C# messages arent sending?
基本上,我需要的是p2p連接,現在我有一個異步服務器和客戶端,它們之間通過TcpClient
通信。 問題是服務器很少檢測到傳入消息,通常只接收第一條消息。 我的服務器代碼在這里:
public void RecieveAsync()
{
if (netStream == null) netStream = Server.GetStream();
netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);
}
public void recieveCallBack(IAsyncResult ar)
{
//try
//{
int rec = netStream.EndRead(ar);
if (rec == 0)
{
if (Disconnected != null)
{
Disconnected(this);
return;
}
}
else
{
if (DataRecieved != null)
{
string RecievedData = Encoding.ASCII.GetString(ReadBuffer, 0, rec);
DataRecieved(RecievedData);
}
ReadBuffer = new byte[1024];
}
}
並且發送數據的客戶端代碼在此處(將其包裝到while循環中,並使用Thread.Sleep(1)
反復發送數據,以更新玩家位置)
public void Send(byte[] data, int index, int length)
{
//add data as state
//socket.NoDelay = true;
Buffer.BlockCopy(data, 0, writeBuffer, index, length);
if (netStream == null) netStream = TcpClient.GetStream();
netStream.BeginWrite(writeBuffer, 0, writeBuffer.Length, sendCallback, netStream);
}
private void sendCallback(IAsyncResult ar)
{
//try
//{
netStream.EndWrite(ar);
//if (ar.AsyncState != null)
//{
// byte[] buffer = (byte[])ar.AsyncState;
// socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, sendCallback, null);
// return;
//}
if (OnSend != null)
{
OnSend(this);
}
//catch (Exception ex)
//{
// System.Windows.Forms.MessageBox.Show(ex.ToString());
// return;
//}
}
默認緩沖區大小為1024,並且僅在netStream.DataAvailible
為true時才調用RecieveAsync
,該事件會不斷地在服務器循環中進行檢查。
編輯::
這是調用服務器的代碼
while (true)
{
byte[] playerData = NormalText(PreparePlayerData());
server.Send(playerData, 0, playerData.Length);
if (server.Server.Connected)
{
server.netStream = server.Server.GetStream();
while (server.netStream.DataAvailable)
{
server.RecieveAsync();
server.netStream = server.Server.GetStream();
}
}
Thread.Sleep(1);
}
在進行網絡編程時,有助於了解各種方法背后的情況。 對於您的receive方法,您可以使用正確配置回調
netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);
當接收到數據時,這將觸發recieveCallBack(),但下面的行開始變得有趣。 還值得注意的是,對netStream.BeginRead的單個調用只會觸發一次回調。 如果要繼續偵聽數據,則需要再次調用netStream.BeginRead。
string RecievedData = Encoding.ASCII.GetString(ReadBuffer, 0, rec);
該框架不能保證您將收到在發送中寫入的所有數據。 收到一些數據后,您需要確定所有內容,然后再嘗試將其轉換回字符串。 如果您還沒有收到所有信息,則需要再次撥打
netStream.BeginRead(ReadBuffer, 0, ReadBuffer.Length, recieveCallBack, netStream);
然后等待更多。
這是編程中的一個棘手方面,但是您顯然進展順利。 如果有助於從工作示例中進行回退,請在此處簽出方法IncomingTCPPacketHandler()(與您的recieveCallBack方法等效) ,該方法來自開源網絡庫networkcomms.net 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.