关于Socket异步编程的思路

问题描述

这几天一直在研究关于Socket的编程,因为之前完全没接触过,在网上查了很多关于这方面的资料,感觉雷同的很多,不知道为什么异步的时候还加个信号量处理,还有主要是目前需要同时连接两个服务器,客户端需要对不同的服务器传回的数据进行处理,如果采用异步的方法,有好几个回调方法,一个服务器还好,如果多出几个服务器,难道那些回调方法需要再重写一遍吗?而且异步的回调除了IAsyncResultar,又没法传递其他参数,而且也没有返回值,不知何解,可能主要是流程不太清楚把,网上都是前篇一律,不知道谁做过这方面比较稳定的程序,指导指导。

解决方案

解决方案二:
你先搞清楚一台服务器先,如果使用异步的话,实际上加一个循环就可以了,GetAddress函数就是包含多个服务器地址了,在ReceiveMessage函数中解析处理的你过来的数据,参考代码:///<summary>///开始建立通讯///</summary>publicstaticvoidStart(){foreach(variteminGetAddress()){//创建一个Socketvarsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{//连接到指定服务器的指定端口socket.Connect(item.IP,item.Port);if(socket.Connected){Console.WriteLine("{0}:{1}:Conneted....",item.IP,item.Port);Console.WriteLine("waitingfordebug_softwareconnecting...");//实现接受消息的方法socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}}catch(Exceptionex){Console.WriteLine(ex.Message);}}Console.Read();}///<summary>///异步接收数据///</summary>///<paramname="ar"></param>publicstaticvoidReceiveMessage(IAsyncResultar){try{varsocket=ar.AsyncStateasSocket;varlength=socket.EndReceive(ar);//分多次接收byte[]reallData=newbyte[length];Array.Copy(buffer,reallData,reallData.Length);stringdata=BitConverter.ToString(reallData);//递归接收socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}catch(Exceptionex){//如果有连接断开或者数据异常的雷达,开始启用重启模式,重新连接Console.WriteLine(ex.Message);}}

解决方案三:
引用1楼SomethingJack的回复:

你先搞清楚一台服务器先,如果使用异步的话,实际上加一个循环就可以了,GetAddress函数就是包含多个服务器地址了,在ReceiveMessage函数中解析处理的你过来的数据,参考代码:[code=csharp]///<summary>///开始建立通讯///</summary>publicstaticvoidStart(){foreach(variteminGetAddress()){//创建一个Socketvarsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{//连接到指定服务器的指定端口socket.Connect(item.IP,item.Port);if(socket.Connected){Console.WriteLine("{0}:{1}:Conneted....",item.IP,item.Port);Console.WriteLine("waitingfordebug_softwareconnecting...");//实现接受消息的方法socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}}catch(Exceptionex){Console.WriteLine(ex.Message);}}Console.Read();}///<summary>///异步接收数据///</summary>///<paramname="ar"></param>publicstaticvoidReceiveMessage(IAsyncResultar){try{varsocket=ar.AsyncStateasSocket;varlength=socket.EndReceive(ar);//分多次接收byte[]reallData=newbyte[length];Array.Copy(buffer,reallData,reallData.Length);stringdata=BitConverter.ToString(reallData);//递归接收socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,newAsyncCallback(ReceiveMessage),socket);}catch(Exceptionex){//如果有连接断开或者数据异常的雷达,开始启用重启模式,重新连接Console.WriteLine(ex.Message);}}

我做的这个是一个Winform程序,需要button来响应分别连接两个不同服务器,目前Client.cs参照网上的方法是这样写的usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}

[/code]但这个如果是多个服务器该怎么改呢
解决方案四:
[/code]usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}
解决方案五:
怎么格式一直都发不好呢usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Net;usingSystem.Net.Sockets;usingSystem.Text;usingSystem.Threading;namespaceClientDemo{classClient{publicSocketclient=null;publicstaticManualResetEventAllDone=newManualResetEvent(false);publicstringstr=null;publicclassStateObject{publicconstintBufferSize=1024;publicreadonlybyte[]Buffer=newbyte[BufferSize];publicreadonlyStringBuilderSb=newStringBuilder();publicSocketClient;}publicvoidConnect(Socketsocket,EndPointremoteEp){AllDone.Reset();if(!socket.Connected){socket.BeginConnect(remoteEp,ConnectCallBack,socket);}AllDone.WaitOne(200);//Send(socket,GetBytes(Command.LowByteConnect),4);//Receive(socket);}publicvoidConnectCallBack(IAsyncResultar){AllDone.Set();Socketsocket=(Socket)ar.AsyncState;try{if(socket.Connected){socket.EndConnect(ar);}}catch(Exception){throw;}}publicvoidSend(Socketsocket,byte[]byteCom,intlength){if(client!=null&&client.Connected){socket.BeginSend(byteCom,0,length,0,SendCallBack,client);}}publicvoidSendCallBack(IAsyncResultar){try{Socketsocket=(Socket)ar.AsyncState;intbytesSent=socket.EndSend(ar);}catch(Exception){throw;}}publicvoidReceive(Socketsocket){try{StateObjectstate=newStateObject{Client=socket};socket.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}catch(Exception){socket.Close();}}publicvoidReceiveCallBack(IAsyncResultar){try{StateObjectstate=(StateObject)ar.AsyncState;Socketsocket=state.Client;intbytesRead=socket.EndReceive(ar);if(bytesRead>0){state.Sb.Append(Encoding.Default.GetString(state.Buffer,0,bytesRead));Command.ReturnCom(state.Buffer);client.BeginReceive(state.Buffer,0,StateObject.BufferSize,0,ReceiveCallBack,state);}}catch(Exception){//throw;}}}}

时间: 2024-12-22 23:52:51

关于Socket异步编程的思路的相关文章

求教socket异步编程中连接的一点问题,怎样实现客户端连不上服务端的时候一直去连接它

问题描述 假设现在客户要去连接服务端而此时服务端可能没开启或者其他其他原因造成客户端第一次或者前几次都不能够连接到,怎样使得客户在连接失败后继续连接它知道成功? 解决方案 解决方案二:up

java socket异步短连接单工编程

问题描述 java socket异步短连接单工编程 之前没有接触过socket,现在项目中临时用到socket编程,更奇特的是要求异步短连接单工模式,连接的对方是银行,求各位高手赐我一份完整的源码实例,会有高分酬谢.急用! 解决方案 去看一下NIO或AIO吧,可以使用框架的话使用Netty或Mina效果更佳

Javascript异步编程的4种方法

你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境相对单纯:坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行.常见的浏 览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其

Javascript单线程:异步编程的4种方法

你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境相对单纯:坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行.常见的浏 览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其

JavaScript怎么实现异步编程模式?

  你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行.常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,

Android异步编程

Android的线程和内存模型 Android操作系统在boot后,会启动一个Zygote(受精卵)进程,Zygote进程负责创建大部分应用程序进程.Zygote进程启动加载核心程序库和数据结构到内存后会创建一个Dalvik虚拟机(DVM)进程--SystemServer,此进程会包含大部分的系统服务(包括管理Activity的服务ActivityManagerService),SystemServer初始化后,Zygote进程会侦听本地的socket端口, 等待进一步的指令.当新的app被启动

经过一年时间的沉淀 再次回首 TCP Socket服务器编程--转

------------------ 前言 ------------------ 开发了这么多年,发现最困难的程序开发就是通讯系统.   其他大部分系统,例如CRM/CMS/权限框架/MIS之类的,无论怎么复杂,基本上都能够本地代码本地调试,性能也不太重要.(也许这个就是.net的企业级开发的战略吧)   可是来到通讯系统,一切变得困难复杂.原因实在太多了,如: 性能永远是第一位:有时候一个if判断都要考虑性能,毕竟要损耗一个CPU指令,而在通讯系统服务器,每秒钟都产生上百万级别的通讯量,这样一

一篇需要膜拜的文篇--Javascript异步编程模型进化(转)

要我能用得这么熟, 那前端出师了哈. http://foio.github.io/javascript-asyn-pattern/ 改天一个一个亲测一下. Javascript语言是单线程的,没有复杂的同步互斥:但是,这并没有限制它的使用范围:相反,借助于Node,Javascript已经在某些场景下具备通吃前后端的能力了.近几年,多线程同步IO的模式已经在和单线程异步IO的模式的对决中败下阵来,Node也因此得名.接下来我们深入介绍一下Javascript的杀手锏,异步编程的发展历程. 让我们

socket网络编程 文件传输的问题?

问题描述 socket网络编程 文件传输的问题? socket网络编程,目前是同时开启两个进程两个线程,同时从server那端传输两个文件过来,是可以实现,任意格式的文件和任何大小的文件都可以.现在的项目要求是这两个进程要同时传输一个文件.我的思路是一个进程传输该文件的前一半,另一个进程传输该文件的后一半,具体实现就不知道了,希望大家给点意见,已经摸索了好几天.毫无头绪啊!!!!!项目马上就要完成了,谢谢大家. 解决方案 RandomAccessFile,看看吧. 解决方案二: 循序渐进Sock