关于Socket以不接受时 用BeginReceive 发生接受延时,假若服务器端向客户端连续发送A,B,C 客户端接受的时候总会延迟一次接受到,也就是说当服务器端发B时客户端才能收到A,只有服务器再发送C时,客户端才能收到B,相关代码如下,望各位高手慷慨赐教,谢谢!急
public void ReceiveData()
{
try
{
StateObject state = new StateObject();
state.workSocket = Soc;
Soc.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,
new AsyncCallback(ReceiveCallback),state);
}
catch(Exception e)
{
RaiseSockErrEvent("Receive : "+e.Message);
CloseSocket();
}
} /// <summary>
/// ReceiveData的回调函数
/// </summary>
/// <param name="ar">IAsyncResult实例</param>
private void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;//获得调用时传递的StateObject对象
Socket soc = state.workSocket;
int byteRead = soc.EndReceive(ar);
if (byteRead > 0)//判断是否接受到了新信息
{
for(int i=0;i<byteRead;i++)
response.Add(state.buffer[i]); soc.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,
new AsyncCallback(ReceiveCallback),state);//继续接收 问题可能出现在这里 每次都延缓一次才能接受到上次的
}
}
catch(Exception e)
{
RaiseSockErrEvent("Receive : "+e.Message);
CloseSocket();
}
}
public void ReceiveData()
{
try
{
StateObject state = new StateObject();
state.workSocket = Soc;
Soc.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,
new AsyncCallback(ReceiveCallback),state);
}
catch(Exception e)
{
RaiseSockErrEvent("Receive : "+e.Message);
CloseSocket();
}
} /// <summary>
/// ReceiveData的回调函数
/// </summary>
/// <param name="ar">IAsyncResult实例</param>
private void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;//获得调用时传递的StateObject对象
Socket soc = state.workSocket;
int byteRead = soc.EndReceive(ar);
if (byteRead > 0)//判断是否接受到了新信息
{
for(int i=0;i<byteRead;i++)
response.Add(state.buffer[i]); soc.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,
new AsyncCallback(ReceiveCallback),state);//继续接收 问题可能出现在这里 每次都延缓一次才能接受到上次的
}
}
catch(Exception e)
{
RaiseSockErrEvent("Receive : "+e.Message);
CloseSocket();
}
}
“soc.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,
new AsyncCallback(ReceiveCallback),state);//继续接收 问题可能出现在这里 每次都延缓一次才能接受到上次的”
把这个放到for循环的外面试下
我也不知道能不能起作用 我也没有去实验 如果不行还希望把我的留言删掉 以免误导别人 呵呵 同时期待解决问题的答案
-----------------------------------------------------------------
看样子LZ的代码是客户端的吧,其实在客户端根本就没有必要用异步,这样起不到更好的效果,还会得到相反的效果,异步其实只有在服务器端并且连接客户很多的时候才能达到更好的效果,你说的情况可能就是用了异步造成的
Thread t;
public void RecieveDate1()
{
t = new Thread(new ThreadStart(receiveMsg1));
t.Name = "Receive Message"; t.IsBackground = true;
t.Start(); }
public void receiveMsg1()
{
try
{
while (true)
{ byte[] recvBytes = new byte[1024];
int bytes; bytes = Soc.Receive(recvBytes, recvBytes.Length, 0);
for (int i = 0; i < bytes; i++)
{
response.Add(recvBytes[i]);
}
CheckCommand();
} }
catch (Exception ex)
{
RaiseSockErrEvent("Receive Message Error" + ex.Message);
CloseSocket();
} }
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包.
比如 你先发送了"HELLO",再发送"WORLD",理论上来说可能是会分2次收到,但很有可能一次就收到"HELLOWORLD".
这种情况还好,很多都是最后一个包并不是完整的,这样出错的概率就会很大
{
byte[] Buff;
StateObject state;
public event EventHandler<ReceiveMessage> EventMsg;
public void ReceiveData()
{ Buff = new byte[256];
try
{
state = new StateObject();
state.workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
state.workSocket.Connect(new System.Net.IPAddress(new byte[4] { 192, 168, 2, 97 }), 399);
ReceiveDatas(state.workSocket);
//Soc.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None,
//new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
// RaiseSockErrEvent("Receive : " + e.Message);
// CloseSocket();
}
} private void ReceiveDatas(Socket socket)
{
socket.BeginReceive(Buff, 0, Buff.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback), socket);
} /// <summary>
/// ReceiveData的回调函数
/// </summary>
/// <param name="ar"> IAsyncResult实例 </param>
private void ReceiveCallback(IAsyncResult ar)
{
try
{
Socket socket = (Socket)ar.AsyncState;//获得调用时传递的StateObject对象
// Socket soc = state.workSocket;
int byteRead = socket.EndReceive(ar); if (byteRead > 0)//判断是否接受到了新信息
{
//for (int i = 0; i < byteRead; i++)
// response.Add(state.buffer[i]);
if (EventMsg != null)
{
ReceiveMessage e = new ReceiveMessage();
e.msg = Encoding.Default.GetString(Buff);
EventMsg(this, e);
}
socket.BeginReceive(Buff, 0, Buff.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
}
}
catch (Exception e)
{
//RaiseSockErrEvent("Receive : " + e.Message);
// CloseSocket();
}
}
}
public class ReceiveMessage:EventArgs
{
public string msg;
}
public class StateObject
{
public Socket workSocket;
}
由于这半个月出差,一直没有时间搞这个,按照hopewoo 改的程序测了一下还是会出现问题,就是我写个循环向服务器连发20条信息,每条信息服务器应该给回复,但收到只能收到前三条,地21次发送时才能收到第4条的回复,如果一条一条的发送,能按照顺序接受,没有什么问题
希望能得到各位进一步的指教,高手们留个邮箱把,我把整个程序发过去帮忙看看。
我的邮箱[email protected] QQ 272240300
你发给我我帮你看看
我之前也被这个东西弄的头痛死
花开花落,花落花开
等 级:
发表于:2007-12-13 12:05:4713楼 得分:0
非阻塞用于UI上的话,相对友好,如果你接收个大的文件,难道一直让界面处于无响应状态?
fuadam
路西菲尔
等 级:
发表于:2007-12-13 12:10:1114楼 得分:0
同步就会处于无响应,楼上你够搞笑的
hopewoo
花开花落,花落花开
等 级:
发表于:2007-12-13 12:40:5115楼 得分:0
你另开线程来执行这个操作就是另外一回事了.我只是给你举个例子,讲话不要太刻薄你
fuadam
路西菲尔
等 级:
发表于:2007-12-13 13:00:1316楼 得分:0
异步是什么不就是单开线程吗?
hopewoo
花开花落,花落花开
等 级:
发表于:2007-12-13 13:29:3117楼 得分:0
你同步不想阻塞不是也得放在线程里吗?难道挂在主线程里?
hopewoo
花开花落,花落花开
等 级:
发表于:2007-12-13 13:35:1518楼 得分:0
不说这个了,反正各有各的好处,异步存在就肯定有它的价值,同步对传输来说效率是很高,但对于全局程序就不一定,这个道理就和多开线程能提高程序运行效率是一样的.你说"从来就没觉得非阻塞方式有多大用"这话就有点偏激了.
还是帮LZ解决问题吧
-----------------------------------------------------------------------------------------
我不想批什么,只是想说TO:fuadam
一般的服务器程序如果在连接多的情况下都是要用导步的,你所说的“同步就会处于无响应,楼上你够搞笑的”点有那个的味道,如果你用同步没有另开线程的话,UI界面肯定处于假死的状态,一般的.NET同步通讯程序,都是另开线程来接受连接的,这样很不好,如果有1000个连接就开1000个?性能肯定很低下的。导步通讯程序虽然并没有直接使用线程,但也是用了线程,不过这个异步的线程是丢到系统内核去的,甚至是硬件级别上的,这样性能就得到很大的提升了。如果不相信,你可以直接写一个程序试一下我觉得hopewoo对.NET的网络通讯还是理解得比较清楚的,呵呵