完成端口高并发数据接收发送问题

问题描述

我用完成端口做了一个中转服务器,需要同时接收100个客户端每100ms发来一次255bytes的数据,然后将所有收到数据发给另外1客户端。目前接收数据目前没有问题,但转发经常没有发出去。接收使用socket.ReceiveAsync,在回调函数中使用socket.SendAsync发送,发送出去的数据只有接收到的数据的十分之一。usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Net.Sockets;usingSystem.Net;usingSystem.Windows.Forms;namespaceIOCPServer{publicclassClientToken{publicSocketConnectSocket;publicSocketAsyncEventArgsReceiveEventArgs;publicSocketAsyncEventArgsSendEventArgs;protectedbyte[]RecvBuffer;publicClientToken(){ReceiveEventArgs=newSocketAsyncEventArgs();ReceiveEventArgs.UserToken=this;SendEventArgs=newSocketAsyncEventArgs();SendEventArgs.UserToken=this;RecvBuffer=newbyte[1024];ReceiveEventArgs.SetBuffer(RecvBuffer,0,RecvBuffer.Length);}}publicclassIOCPServer{boolIsInit;boolIsRun;SocketlistenSocket;List<ClientToken>ClientList;Objectm_Mutex;publicvoidInit(){if(IsInit==true)return;m_Mutex=null;ClientList=newList<ClientToken>(1);IsInit=true;}publicvoidUnInit(){if(IsInit==false)return;ClientList.Clear();IsInit=false;}publicboolStart(IPEndPointlocalEndPoint){if(IsRun)returntrue;try{listenSocket=newSocket(localEndPoint.AddressFamily,SocketType.Stream,ProtocolType.Tcp);listenSocket.Bind(localEndPoint);listenSocket.Listen(100);}catch(SocketExceptione){if(e.NativeErrorCode==10048)MessageBox.Show("监听端口已经被占用","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);elseMessageBox.Show(e.Message,"提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);returnfalse;}StartAccept(null);IsRun=true;returntrue;}publicvoidStop(){if(IsRun==false)return;try{listenSocket.Close();}catch(ExceptionE){}IsRun=false;}publicvoidStartAccept(SocketAsyncEventArgsacceptEventArgs){if(acceptEventArgs==null){acceptEventArgs=newSocketAsyncEventArgs();acceptEventArgs.Completed+=newEventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);}else{acceptEventArgs.AcceptSocket=null;//释放上次绑定的Socket,等待下一个Socket连接}boolwillRaiseEvent=listenSocket.AcceptAsync(acceptEventArgs);if(!willRaiseEvent){ProcessAccept(acceptEventArgs);}}voidAcceptEventArg_Completed(objectsender,SocketAsyncEventArgsacceptEventArgs){try{if(acceptEventArgs.AcceptSocket.Connected==true)ProcessAccept(acceptEventArgs);}catch(ExceptionE){}}privatevoidProcessAccept(SocketAsyncEventArgsacceptEventArgs){ClientTokencliToken=newClientToken();cliToken.ReceiveEventArgs.Completed+=newEventHandler<SocketAsyncEventArgs>(IO_Completed);cliToken.SendEventArgs.Completed+=newEventHandler<SocketAsyncEventArgs>(IO_Completed);cliToken.ConnectSocket=acceptEventArgs.AcceptSocket;ClientList.Add(cliToken);try{boolwillRaiseEvent=cliToken.ConnectSocket.ReceiveAsync(cliToken.ReceiveEventArgs);//投递接收请求if(!willRaiseEvent){lock(cliToken){ProcessReceive(cliToken.ReceiveEventArgs);}}}catch(ExceptionE){}StartAccept(acceptEventArgs);//把当前异步事件释放,等待下次连接}voidIO_Completed(objectsender,SocketAsyncEventArgsasyncEventArgs){ClientTokencliToken=(ClientToken)asyncEventArgs.UserToken;try{lock(cliToken){if(asyncEventArgs.LastOperation==SocketAsyncOperation.Receive)ProcessReceive(asyncEventArgs);}}catch(ExceptionE){}}privatevoidProcessReceive(SocketAsyncEventArgsreceiveEventArgs){ClientTokencliToken=(ClientToken)receiveEventArgs.UserToken;if(cliToken.ConnectSocket==null)return;if(cliToken.ReceiveEventArgs.BytesTransferred>0&&cliToken.ReceiveEventArgs.SocketError==SocketError.Success){SendAsync(cliToken.ConnectSocket,cliToken.SendEventArgs,cliToken.ReceiveEventArgs.Buffer,cliToken.ReceiveEventArgs.Offset,cliToken.ReceiveEventArgs.BytesTransferred);boolwillRaiseEvent=cliToken.ConnectSocket.ReceiveAsync(cliToken.ReceiveEventArgs);//投递接收请求if(!willRaiseEvent)ProcessReceive(cliToken.ReceiveEventArgs);}else{CloseClientSocket(cliToken);}}publicvoidCloseClientSocket(ClientTokencliToken){if(cliToken.ConnectSocket==null)return;try{cliToken.ConnectSocket.Shutdown(SocketShutdown.Both);}catch(ExceptionE){}cliToken.ConnectSocket.Close();cliToken.ConnectSocket=null;ClientList.Remove(cliToken);}publicboolSendAsync(SocketconnectSocket,SocketAsyncEventArgssendEventArgs,byte[]buffer,intoffset,intcount){if(connectSocket==null)returnfalse;boolwillRaiseEvent=true;try{sendEventArgs.SetBuffer(buffer,offset,count);willRaiseEvent=connectSocket.SendAsync(sendEventArgs);}catch(ExceptionE){returnfalse;}returnfalse;}}}

解决方案

本帖最后由 bj_leo_3000 于 2016-01-14 11:31:59 编辑
解决方案二:
哪位高手给解释一下。
解决方案三:
既然accept没问题,那可以考虑将accept的数据放入队列,然后开个线程从队列中取消息进行发送
解决方案四:
有些一眼可以看出的问题。例如:publicclassClientToken{publicSocketConnectSocket;publicSocketAsyncEventArgsReceiveEventArgs;publicSocketAsyncEventArgsSendEventArgs;...........这里,第一个定义毫无意义,你根本没有用到,删除多余的代码才能保证代码质量。而后边两个定义,至少有一个你肯定在代码中产生了“并发冲突”情况发生时去丢失了其真正要处理数据。要么是ReceiveEventArgs,要么是SendEventArgs,你肯定有一个地方明明应该创建多个对象实例,而为了空洞地“共享使用”这种噱头而共享使用了公共对象实例。
解决方案五:
另外可以直接看到一堆“小问题”,例如:1.使用所谓IOCP,不用newSocket,而要使用newTcpListener机制,然后充其量地,TcpListener对象的Socket属性可以用。不要写newSocket(.......)这种代码。2.人家的TcpListener内置的Listen(int.MaxValue)代码。而不是什么Listen(100)。3.Buffer大小是怎样确定为1024的?这个Buffer不是底层tcp机制的buffer,这个大小通常开到几百K才能发挥最好的效果。还有监听的地址应该是本机的所有网卡地址,等等问题,就不多说了。也没有时间去细看。

时间: 2024-11-10 00:34:10

完成端口高并发数据接收发送问题的相关文章

Apache Spark技术实战(四)spark-submit常见问题及其解决 &amp;CassandraRDD高并发数据读取实现剖析

<一>spark-submit常见问题及其解决 概要 编写了独立运行的Spark Application之后,需要将其提交到Spark Cluster中运行,一般会采用spark-submit来进行应用的提交,在使用spark-submit的过程中,有哪些事情需要注意的呢? 本文试就此做一个小小的总结. spark-defaults.conf Spark-defaults.conf的作用范围要搞清楚,编辑driver所在机器上的spark-defaults.conf,该文件会影响 到drive

多线程-求 有关 高并发 数据区 读取更新 数据 的解决办法

问题描述 求 有关 高并发 数据区 读取更新 数据 的解决办法 问题:高并发 数据库取数据,每次取到一条数据后更新这条数据的状态为已取用过. 环境:3台服务器跑应用 处理请求,多线程数据库取数据 有点类似 12306的买票,查找过资料 有看到 1W人 同时抢一张票的问题. 现在考虑的问题是,如果票是足够多的,如何解决高并发取数据冲突的问题,如果用加锁的方式,会出现大量请求都取一条数据,导致 等待时间太长. 有没有 好的方案,可以避免同时请求到同一条数据. 解决方案 可以用大数据分布式云计算物联网

大数据量下高并发同步的讲解(不看,保证你后悔)(转)

  对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研究一下常见的并发和同步吧. 为了更好的理解并发和同步,我们需要先明白两个重要的概念:同步和异步 1.同步和异步的区别和联系 所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到 返回的值或消息后才往下执行其它的命令. 异步,执行完函数或方法后

云HBase全面支持金融云可用区-支持实时安全风控\金融时序\大数据量存储及高并发访问

前言 HBase已经全面支持金融云的业务,包括华东1.华东2.华南区域.HBase是一个通用的数据库,在金融云场景下有较多的需求,本文主要分析hbase解决哪些金融场景的需求 金融云实时风控 在安全风控的场景下,我们往往需求存储大量的结构化数据,主要因为越多的数据,画像风控越精准,阿里蚂蚁金融实时风控流程图如下: 1.数据源会产生在各个地方,以事件为中心,事件有很多的属性,比如:人物.行为.环境.时间 等,会高并发的入库操作. 2.离线分析,我们往往会对历史数据进行较高的并发分析,分析完成后.要

高并发系统数据幂等的技术尝试

前言介绍 在系统开发过程中,经常遇到数据重复插入.重复更新.消息重发发送等等问题,因为应用系统的复杂逻辑以及网络交互存在的不确定性,会导致这一重复现象,但是有些逻辑是需要有幂等特性的,否则造成的后果会比较严重,例如订单重复创建,这时候带来的问题可是非同一般啊. 什么是系统的幂等性 幂等是数据中得一个概念,表示N次变换和1次变换的结果相同. 高并发的系统如何保证幂等性 查询API 查询的API,可以说是天然的幂等性,因为你查询一次和查询两次,对于系统来讲,没有任何数据的变更,所以,查询一次和查询多

解决网络不通数据只发送不接收

网络的畅通是表现在既有发送包,也有接收包,只有来去都畅通才正常.但是如果只有发送,却没有接收,碰到这样的故障到底又是怎么回事呢?在笔者短暂的两年网管生涯中,出现了几次这样的故障,但他们发生的原因又各有不同.今天笔者就把一些解决方法奉献给大家. 一般来说,出现这种故障的时候,网络连接都是都是好的,即不会出现红色的叉子图标.但这又只是一种表现的正常,因此我们入手的时候必须先从自身入手. 从自身入手的第一点就是检查出现该故障前有没有安装过什么软件,有没有改过什么设置,尤其是杀毒软件.防火墙这一类的软件

表格存储:使用TableStoreWriter进行高并发、高吞吐的数据写入

概述     表格存储(原OTS)的一大特性是能够支撑海量数据的高并发.高吞吐率的写入,特别适合日志数据或物联网场景(例如轨迹追踪或溯源)数据的写入和存储.这些场景的特性是,会在短时间内产生大量的数据需要消化并写入数据库,需要数据库能够提供高并发.高吞吐率的写入性能,需要满足每秒上万行甚至上百万行的写入吞吐率.针对这些场景,我们在存储层做了很多的优化(本篇文章不赘述),同时在SDK接口层也做了一些优化,专门提供了一个简单易用.高性能的数据导入接口.     TableStoreWriter是基于

udp协议的数据接收与发送的代码

我想基于lwIP协议中的UDP协议,用单片机做一个服务器,接受电脑的指令然后返回数据.以下是我的代码 /**************************************************** *函数功能:初始化udp,选定通信端口,建立连接机制 ****************************************************/ void Udp_Api_init(void) {   err_t err;   struct udp_pcb *UDPpcb;

大数据量高并发的数据库优化详解_MsSql

如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. 一.数据库结构的设计 在一个系统分析.设计阶段,因为数据量较小,负荷较低.我们往往只注意到功能的实现,而很难注意到性能的薄弱之处,等到系统投入实际运行一段时间后,才发现系统的性能在降低,这时再来考虑提高系统性能则要花费更多的人力物力,而整个系统也不可避免的形成了一个打补丁工程. 所以在考虑整个系统的流程的时候,我们必须