今天想写一个IOCP的服务器端软件;其实俺在银行,电力公司要跟我们链接,进行电费收取;
电力的前置机作为客户端,这个前置机链接到我的服务器上,建立一个长链接,除非客户端主动退出,否则这个链接一直保持不断;电力方的各个窗口软件链接到电力的前置机上,通过前置机跟我们银行建立的这个长链接跟我们交互报文;所以电力客户方就有可能通过这个链接频繁的发起报文到我的服务器上;
假设有三个电力窗口同时发起交易报文过来,报文1,报文2,报文3,这三个报文是非定常的,而且不带报文长度,但是每个报文有结束符标志,是"回车换行"当作每个报文的结束符;
由于TCP的有序性,所以在我的socket上,报文1、报文2、报文3是不会交叉在一块的,肯定是一个完整报文【假设是2】,然后再下一个完整报文【假设是3】,然后再下一个【报文1】;
所以在我的socket上有三个报文过来:{报文2内容+结束符}+{报文3内容+结束符}+{报文1内容+结束符}我想用IOCP完成端口模型来读取报文;
我想问一个问题,如果我投递一个WSARECV请求,假设buffer足够大,足够可以容下报文2内容+结束符,而且还有剩余,那么会不会把后面的报文也读取一段进来?如果会,这样就问题就大,报文就错了;但是我看http://www.cppblog.com/sherrylso/archive/2008/06/23/30858.html里面的 RedFox 的回复:IOCP 只處理封包,收到一個完整的包後,就POST到工作線程池,由工作線程池進行分配線程處理;
我感觉好像不会发生我说的那种问题,因为TCP包是“封起来”的包;
假设buffer足够大,是不是IOCP读到一个包的“封尾”,就会POST到工作者线程池里面去??还是说IOCP只要buffer足够大,就会把socket上的报文全部读进来?
电力的前置机作为客户端,这个前置机链接到我的服务器上,建立一个长链接,除非客户端主动退出,否则这个链接一直保持不断;电力方的各个窗口软件链接到电力的前置机上,通过前置机跟我们银行建立的这个长链接跟我们交互报文;所以电力客户方就有可能通过这个链接频繁的发起报文到我的服务器上;
假设有三个电力窗口同时发起交易报文过来,报文1,报文2,报文3,这三个报文是非定常的,而且不带报文长度,但是每个报文有结束符标志,是"回车换行"当作每个报文的结束符;
由于TCP的有序性,所以在我的socket上,报文1、报文2、报文3是不会交叉在一块的,肯定是一个完整报文【假设是2】,然后再下一个完整报文【假设是3】,然后再下一个【报文1】;
所以在我的socket上有三个报文过来:{报文2内容+结束符}+{报文3内容+结束符}+{报文1内容+结束符}我想用IOCP完成端口模型来读取报文;
我想问一个问题,如果我投递一个WSARECV请求,假设buffer足够大,足够可以容下报文2内容+结束符,而且还有剩余,那么会不会把后面的报文也读取一段进来?如果会,这样就问题就大,报文就错了;但是我看http://www.cppblog.com/sherrylso/archive/2008/06/23/30858.html里面的 RedFox 的回复:IOCP 只處理封包,收到一個完整的包後,就POST到工作線程池,由工作線程池進行分配線程處理;
我感觉好像不会发生我说的那种问题,因为TCP包是“封起来”的包;
假设buffer足够大,是不是IOCP读到一个包的“封尾”,就会POST到工作者线程池里面去??还是说IOCP只要buffer足够大,就会把socket上的报文全部读进来?
另外,不可能加长度,因为报文是按照结束符来的,而且不是我说了算的,是对方定的格式;
private void EncodingBytes(byte[] Totalbytes, int TotalBytesCount)
{
// Thread.Sleep(10000);
try
{ if (Totalbytes.Length <= 5)
{
DataBufferLast = new byte[TotalBytesCount];
Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);
return;
} byte[] TempHeadBytes = new byte[4];
Buffer.BlockCopy(Totalbytes, 1, TempHeadBytes, 0, 4);
int TempPackLen = BitConverter.ToInt32(TempHeadBytes, 0); //每个包的长度
if ((TempPackLen + DataHeadLen) > TotalBytesCount)
{
DataBufferSizeLast = TotalBytesCount;
DataBufferLast = new byte[TotalBytesCount];
Buffer.BlockCopy(Totalbytes, 0, DataBufferLast, 0, TotalBytesCount);
return;
}
byte[] TempPackBytes = new byte[TempPackLen];
for (int i = 0; i < TempPackLen; i++)
{
TempPackBytes[i] = Totalbytes[i + DataHeadLen];
}
//string receivedStr = System.Text.Encoding.Default.GetString(TempPackBytes);
if (onMyDelegate != null)
{
////--
//ThreadWithPara para = new ThreadWithPara(System.Text.Encoding.Default.GetString(TempPackBytes), onMyDelegate);
//Thread t = new Thread(new ThreadStart(para.ThreadProc));
//t.Start();
//t.IsBackground = true;
////-- onMyDelegate(System.Text.Encoding.Default.GetString(TempPackBytes)); //----------------------------------------------------------------事件
}
else
{
Log.Info("onMyDelegate事件为空!");
}
if (TotalBytesCount > DataHeadLen + TempPackLen)
{
byte[] Bytes = new byte[TotalBytesCount - DataHeadLen - TempPackLen];
Buffer.BlockCopy(Totalbytes, DataHeadLen + TempPackLen, Bytes, 0, TotalBytesCount - DataHeadLen - TempPackLen);
this.EncodingBytes(Bytes, TotalBytesCount - DataHeadLen - TempPackLen);
}
} catch (SocketException ex)
{
Log.Info("EncodingBytes:" + ex.Message + "ErrorCode:" + ex.ErrorCode.ToString());
}
catch (Exception ex)
{
Log.Info("EncodingBytes:" + ex.Message);
}
} 看下关键的代码段