异步通信中必须要等Server端断掉后才能接收到数据,这是为什么?

uheart 2009-02-13 04:01:46
搞了半天 不知道怎么回事,Server端已经返回数据,但就是接收不到,非要等Server端断开后才能接收到 晕死了
SendCmd为前台ajax调用,Server能接收到我发送的命令.
[AjaxPro.AjaxMethod]
public string SendCmd(string cmd)
{
string str = "";

try
{

byte[] bytData = this.GetCmdPacket(cmd); //获得发送数据内容

str = SendCommand(bytData); //发送命令,并接收Server返回内容
}
catch(Exception ce)
{
str=ce.Message;
}
return str;
}


private const int port = 6205;
private const string ServerIp = "192.168.2.100";


private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);

private static String response = String.Empty;
public static PacketObj pc = new PacketObj();



//生成发送的内容
public byte[] GetCmdPacket(byte[] cmdPar)
{

byte[] bytCmd = new byte[4096];
byte bytStatus = 0x10 | 0xe0;
byte[] ClientID = new byte[]{0x31,0x31,0x30,0x31};
byte[] SiteID = new byte[]{0x61,0x31,0x30,0x31};
byte ProtocolCommand = 0x07;

//生成最终的内容包
bytCmd = pc.MergerPacket(bytStatus,ClientID,SiteID,ProtocolCommand,cmdPar);

return bytCmd;
}


private string SendCommand(byte[] byteData)
{
try
{
//建立与Server的连接
IPAddress ip = IPAddress.Parse(ServerIp);
IPEndPoint remoteEP = new IPEndPoint(ip, port);
Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect( remoteEP,new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();

//发送
Send(client,byteData);
sendDone.WaitOne();

//接收
Receive(client);
receiveDone.WaitOne();

client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return response;
}

//连接回调方法
private void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket) ar.AsyncState;
client.EndConnect(ar);
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

//发送
private static void Send(Socket client, byte[] byteData)
{
client.BeginSend(byteData,0,pc.PacketLen,0,new AsyncCallback(SendCallback),client);
}

发送回调
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket) ar.AsyncState;
int bytesSent = client.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

//接收
private void Receive(Socket client)
{
try
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

//接收回调
private void ReceiveCallback( IAsyncResult ar )
{
try
{
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));

client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

public class StateObject
{

public Socket workSocket = null;

public const int BufferSize = 256;

public byte[] buffer = new byte[BufferSize];

public StringBuilder sb = new StringBuilder();
}
...全文
164 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
uheart 2009-02-16
  • 打赏
  • 举报
回复
up
uheart 2009-02-15
  • 打赏
  • 举报
回复
Server端的数据已发送了 而且程序全部走完了,我收不到他发送的内容,但是只要一关闭Server端的程序 我马上就能接收到 晕死人了,其它客户端都可以正常接收
Fibona 2009-02-13
  • 打赏
  • 举报
回复
异步接分本身就有这种问题,所以你可以通过发送时,加一个\0做为结束符

然后参考一下下面的接收代码
protected void CallBackReceive(IAsyncResult asyncResult)
{
StateObject state = (StateObject)asyncResult.AsyncState;
try
{
if ((state.socket == null) || (!state.socket.Connected) || (!this.serverRunTag) )
{
return;
}

state.receiveSize = state.socket.EndReceive(asyncResult);
if (state.receiveSize > 0)
{
state.stream.Seek(state.streamLength, System.IO.SeekOrigin.Begin);
state.stream.Write(state.buff,0, state.receiveSize);
state.streamLength += state.receiveSize;
//
if (state.buff[state.receiveSize-1]!=byte.Parse("0"))
{
if (state.socket.Available > 0)
{
state.socket.BeginReceive(state.buff, 0, state.buff.Length, SocketFlags.None, new AsyncCallback(CallBackReceive), state);
return;
}
}
else
{
//消息处理
this.ReceiveCompleteHandle(state);
}
}
if (state.socket != null)
if (state.socket.Connected)
state.socket.BeginReceive(state.buff, 0, state.buff.Length, SocketFlags.None, new AsyncCallback(CallBackReceive), state);

}
catch (SocketException e)
{
//处理错误
}
}
路人乙e 2009-02-13
  • 打赏
  • 举报
回复
楼主的具体描述暂不考虑,单说问题,异步请求当然要等server端完成所有动作才能返回
ztenv 2009-02-13
  • 打赏
  • 举报
回复
的确挺长的,建议楼主先详细描述问题;
net_boy 2009-02-13
  • 打赏
  • 举报
回复
//接收
Receive(client);
receiveDone.WaitOne();
换成
while (true)
{
//receive
ReceiveDone.Reset();
ReceiveData(_ClientSocket);
ReceiveDone.WaitOne();
}
uheart 2009-02-13
  • 打赏
  • 举报
回复
LQknife 2009-02-13
  • 打赏
  • 举报
回复
代码好长啊,帮楼主顶
uheart 2009-02-13
  • 打赏
  • 举报
回复
up
uheart 2009-02-13
  • 打赏
  • 举报
回复
Server端有问题的可能性不太大 其它客户端能收到Server端发送的数据

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧