TCP 多线程 同时发送大量数据 解决办法

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mangshe0/article/details/82923899

向大家分享一下.呵呵 服务器向多个终端传输大量数据。并且同时向他们发送,采用安全的TCP方式。我采用的办法是 首先向多个终端 创建SOCKET数组,创建多个线程 创建多个线程的目的不是要 每个线程向不同的终端发送,而是每个线程发送不同的数据,比如一个1G的数据,我线程1取出他的100M内容第二个线程取出他的第二个100M内容。然后线程同步执行向终端数组里面发送。大大的提高了速率.

服务器端对数据进行分割,然后终端 继续对应多个线程去接收这些发来的分割后的数据,然后再拼装在一起。

tcp/ip详解卷1值得看一下。

传输层:
对于UDP协议来说,整个包的最大长度为65535,其中包头长度是65535-20=65515;
对于TCP协议来说,整个包的最大长度是由最大传输大小(MSS,Maxitum Segment Size)决定,MSS就是TCP数据包每次能够传
输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需
要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值
确定为这次连接的最大MSS值。

IP层:

对于IP协议来说,IP包的大小由MTU决定(IP数据包长度就是MTU-28(包头长度)。 MTU值越大,封包就越大,理论上可增加传送速率,但
MTU值又不能设得太大,因为封包太大,传送时出现错误的机会大增。一般默认的设置,PPPoE连接的最高MTU值是1492, 而以太网
(Ethernet)的最高MTU值则是1500,而在Internet上,默认的MTU大小是576字节

展开阅读全文
博主设置当前文章不允许评论。

TCP send 发送大量数据的问题 怎么保证不丢包

07-01

小弟自己写了个局域网传送文件的小程序 子啊调试的时候遇到了几个小问题,在网上找了好久还是没有找到满意的答案特来求助各位大牛。rn1.在发送文件的服务端 要发送大量的数据给客户端,自己定义的协议包,每次发送的字节都是该包的大小,所以接受的时候,也是按这个大小来接受,应该不会产生粘包的问题吧,我在客户端处理的里面也是开了2个线程进行处理,一个负责接受到了直接放到我自己定义的缓冲区中,另一个线程进行在缓冲区里面处理数据,客户端不存在那种长时间不接受数据的问题,所以现在遇到的问题我就有些想不通,服务端Send数据返回的值是正确的,但还是有几率导致数据丢包,这个是什么原因?我在每次发送完了sleep一下几率就降下来太多了,客户端每次都是接受固定的数据,还有Sleep的必要么?还是网络收发数据有个速率的控制?应该控制rn每秒发送数据的多少在上层上?还是底层的TCP协议自己控制,要是底层的话有流量控制,当我上层不停的发送大量的数据的时候,是不是当缓冲区满的时候,包就被弃包了? rn2.还有为了保证每次的整个的大文件数据都能全部被接受,是不是的每次接受完判断一下,假如没有完全接受的话,在重新发送,TCP虽然是可靠的,当这不保证send成功对面就一定能接受到数据这个说法对不?rn 论坛

多线程发送,接收串口数据

08-26

目前多线程接收,解析数据处理好了,但用多线程发送数据时数据出了问题,一是有些指令没有数据返回,二是线程执行顺序是错了,我是用c#.NET 线程池处理的rnrn小弟想实现这样的功能,用多线程发送数据,多线程接收数据,多线程解析数据,保证实时读取串口接收的数据。可下面贴出来的这些方法没有实现要的功能,琢磨了快一个星期了,希望各位大哥指教,能给好的指导思想,有串口多线程发送,接收的项目例子更好。rnrn /// rn /// 发送多条指令,用异步的方式接收数据rn /// rn /// 发送的数据和读取返回的数据)rn /// true 读取返回的数据 false 不返回数据)rn /// rn public bool SendData(string[] cmd, string tagData, bool fag)rn rn DateTime a1 = DateTime.Now;rn //for (int i = 0; i < 1000; i++)rn //rn foreach (string s in cmd)rn rn if (s == string.Empty || tagData == string.Empty)rn return false;rn if (!serialState)rn this.InitPortCom();rn tab = parms.PtlParms(s);rn if (tab == null || tab.Rows.Count == 0)rn return false;rn DataRow frameData = tab.Select(string.Format("type='0' and name='1' ", "Output", "命令长度"))[0];rn int frameLen = Convert.ToInt32(basefun.valtag(frameData["pms"].ToString(), "命令长度")) * 2 + 12;rn byte[] buffData = analy.SetPtlData(tab, tagData);rn serialPort.Write(buffData, 0, buffData.Length);rn this.WaiteSendData(new SendTaskInfo(buffData, s));rn this.WaiteReceiveData(new ReceiveTaskInfo(s, frameLen));rn this.WaitAnalysisData(new ReceiveTaskInfo(s, frameLen));rn rn return true;rn rnrn /// rn /// 开启线程循环发送数据rn /// rn private void WaiteSendData(object data)rn rn if (!serialPort.IsOpen) rn return;rn SendTaskInfo state = data as SendTaskInfo;rn System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadSend), state);rn rnrn /// rn /// 开启线程循环取帧rn /// rn private void WaiteReceiveData(object data)rn rn if (!serialPort.IsOpen) return;rn ReceiveTaskInfo state = data as ReceiveTaskInfo; rn System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ThreadReceive), state);rn rnrn /// rn /// 开启线程解析数据rn /// rn /// rn private void WaitAnalysisData(object data)rn rn if (!serialPort.IsOpen) return;rn ReceiveTaskInfo state = data as ReceiveTaskInfo;rn System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(GetData), state);rn rnrn /// rn /// 开启一个线程发送数据rn /// rn /// rn private void ThreadSend(object state)rn rn SendTaskInfo send = state as SendTaskInfo;rn lock (ThreadObject)rn rn Debug.Write("ThreadSendOne" + " " + send.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn SendTaskInfo data = state as SendTaskInfo;rn byte[] buffData = data.sendData;rn serialPort.Write(buffData, 0, buffData.Length);rn Debug.Write("ThreadSendTwo" + " " + System.Text.Encoding.ASCII.GetString(buffData) + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn Thread.Sleep(300);rn rn rnrnrn /// rn /// 开启一个线程接收数据rn /// rn /// rn private void ThreadReceive(object state)rn rn ReceiveTaskInfo task = state as ReceiveTaskInfo;rn List tmpList = new List();rn Debug.Write("ThreadReceive1" + " " + task.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn bool lenState = false;rn //manulReadEvent.Reset();rn //bool fag = manulReadEvent.WaitOne();rn //if (!fag) return;rn lock (ThreadObject)rn rn while (!lenState)rn rn if (serialPort.BytesToRead > 0)rn rn byte[] buff = new byte[serialPort.BytesToRead];rn serialPort.Read(buff, 0, buff.Length);rn tmpList.AddRange(buff);rn if (tmpList.Count != task.cmdLen)rn continue;rn elsern rn lenState = true;rn Debug.Write("ThreadReceive2" + " " + tmpList.Count + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn returnBuff.Enqueue(tmpList.GetRange(0, task.cmdLen).ToArray());rn tmpList.Clear();rnrn //manulWriteEvent.Set();rn rn rn elsern break;rn rn rn rnrn /// rn /// 解析数据rn /// rn /// rn private void WaitAnalysisData(object data)rn rn if (!serialPort.IsOpen) return;rn ReceiveTaskInfo state = data as ReceiveTaskInfo;rn System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(GetData), state);rn rnrn /// rn /// 解析串口数据rn /// rn /// rn private void GetData(object state)rn rn if (tab == null || tab.Rows.Count == 0 || returnBuff.Count == 0)rn return;rn ReceiveTaskInfo task = state as ReceiveTaskInfo;rn Debug.Write("GetData:" + task.cmdName + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn byte[] buffAll = new byte[0];rn lock (QueueObject)rn rn Debug.Write("returnBuff.Count:" + returnBuff.Count + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn buffAll = returnBuff.Dequeue();rn Debug.Write("buffAll.Count:" + buffAll.Length + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn string len = string.Empty;rn int frameLen = 0;rn byte[] buffTemp = new byte[4];rn for (int i = 0; i < 4; i++)rn rn buffTemp[i] = buffAll[i + 5];rn rn len = GetAscByByte(buffTemp);rn frameLen = Convert.ToInt16(len, 16) + 8;rn if (buffAll.Length < frameLen)rn return;rnrn string returnStr = string.Empty;rn returnStr = GetAscByByte(buffAll);rn Debug.Write(returnStr + ":" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn bool fag = analy.GetPtlData(tab, returnStr, ref data);rn if (!fag) return;rn if (returnData.ContainsKey(task.cmdName.Trim()))rn rn returnData.Remove(task.cmdName.Trim());rn returnData.Add(task.cmdName.Trim(), data);rn rn elsern rn returnData.Add(task.cmdName, data);rn rn Debug.Write(data + "1:" + DateTime.Now.ToString("mm:ss.ffff") + "\r\n");rn if (dataFromPromEventHandle != null)rn dataFromPromEventHandle(this, null);rn Thread.Sleep(300);rn rn rn 论坛

没有更多推荐了,返回首页