您当前的位置:首页 > 今日分享头条 > 正文

socket编程实验(socket实现过程,具体用的方法;怎么实现异步socket)

当有连接接入后系统会自动调用会调用回调函数,下面是服务器端对关于TcpListener类使用BeginAccetpTcpClient方法处理一个传入的连接尝试,在客户端则通过BeginConnect方法和EndConnect方法来实现与服务器的连接,并在函数的第一句就调用Set方法让处于等待的线程可以继续执行libevent是怎么把signal集成到事件主循环框架中的Socket pair就是一个socket对,服务器可以使用BeginAccept方法和EndAccept方法来完成连接到客户端的任务,以下是使用BeginAccetpTcpClient方法和EndAccetpTcpClient方法的代码:复制代码public static void DoBeginAccept(TcpListener listner){ //开始从客户端监听连接 Console.WriteLine(“Waitting for a connection“); //接收连接 //开始准备接入新的连接,BeginConnect方法和EndConnect方法可用于客户端尝试建立与服务端的连接,如果连接没问题就去想一下会不会是ARP问题。

socket实现过程,具体用的方法;怎么实现异步socket

基于C#的socket编程的TCP异步实现一、摘要  本篇博文阐述基于TCP通信协议的异步实现。二、实验平台  Visual Studio 2010三、异步通信实现原理及常用方法3.1 建立连接   在同步模式中,在服务器上使用Accept方法接入连接请求,而在客户端则使用Connect方法来连接服务器。相对地,在异步模式下,服务器可以使用BeginAccept方法和EndAccept方法来完成连接到客户端的任务,在客户端则通过BeginConnect方法和EndConnect方法来实现与服务器的连接。  BeginAccept在异步方式下传入的连接尝试,它允许其他动作而不必等待连接建立才继续执行后面程序。在调用BeginAccept之前,必须使用Listen方法来侦听是否有连接请求,BeginAccept的函数原型为:BeginAccept(AsyncCallback AsyncCallback, Ojbect state)参数:AsyncCallBack:代表回调函数state:表示状态信息,必须保证state中包含socket的句柄  使用BeginAccept的基本流程是:(1)创建本地终节点,并新建套接字与本地终节点进行绑定;(2)在端口上侦听是否有新的连接请求;(3)请求开始接入新的连接,传入Socket的实例或者StateOjbect的实例。  参考代码:复制代码//定义IP地址IPAddress local = IPAddress.Parse(“127.0,0,1“);IPEndPoint iep = new IPEndPoint(local,13000);//创建服务器的socket对象Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);server.Bind(iep);server.Listen(20);server.BeginAccecpt(new AsyncCallback(Accept),server);复制代码  当BeginAccept()方法调用结束后,一旦新的连接发生,将调用回调函数,而该回调函数必须包括用来结束接入连接操作的EndAccept()方法。该方法参数列表为 Socket EndAccept(IAsyncResult iar)下面为回调函数的实例:复制代码void Accept(IAsyncResult iar){ //还原传入的原始套接字 Socket MyServer = (Socket)iar.AsyncState; //在原始套接字上调用EndAccept方法,返回新的套接字 Socket service = MyServer.EndAccept(iar);}复制代码  至此,服务器端已经准备好了。客户端应通过BeginConnect方法和EndConnect来远程连接主机。在调用BeginConnect方法时必须注册相应的回调函数并且至少传递一个Socket的实例给state参数,以保证EndConnect方法中能使用原始的套接字。下面是一段是BeginConnect的调用:Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp)IPAddress ip=IPAddress.Parse(“127.0.0.1“);IPEndPoint iep=new IPEndPoint(ip,13000);socket.BeginConnect(iep, new AsyncCallback(Connect),socket);  EndConnect是一种阻塞方法,用于完成BeginConnect方法的异步连接诶远程主机的请求。在注册了回调函数后必须接收BeginConnect方法返回的IASynccReuslt作为参数。下面为代码演示:复制代码void Connect(IAsyncResult iar){ Socket client=(Socket)iar.AsyncState; try { client.EndConnect(iar); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { }}复制代码  除了采用上述方法建立连接之后,也可以采用TcpListener类里面的方法进行连接建立。下面是服务器端对关于TcpListener类使用BeginAccetpTcpClient方法处理一个传入的连接尝试。以下是使用BeginAccetpTcpClient方法和EndAccetpTcpClient方法的代码:复制代码public static void DoBeginAccept(TcpListener listner){ //开始从客户端监听连接 Console.WriteLine(“Waitting for a connection“); //接收连接 //开始准备接入新的连接,一旦有新连接尝试则调用回调函数DoAcceptTcpCliet listner.BeginAcceptTcpClient(new AsyncCallback(DoAcceptTcpCliet), listner);}//处理客户端的连接public static void DoAcceptTcpCliet(IAsyncResult iar){ //还原原始的TcpListner对象 TcpListener listener = (TcpListener)iar.AsyncState; //完成连接的动作,并返回新的TcpClient TcpClient client = listener.EndAcceptTcpClient(iar); Console.WriteLine(“连接成功“);}复制代码  代码的处理逻辑为:(1)调用BeginAccetpTcpClient方法开开始连接新的连接,当连接视图发生时,回调函数被调用以完成连接操作;(2)上面DoAcceptTcpCliet方法通过AsyncState属性获得由BeginAcceptTcpClient传入的listner实例;(3)在得到listener对象后,用它调用EndAcceptTcpClient方法,该方法返回新的包含客户端信息的TcpClient。  BeginConnect方法和EndConnect方法可用于客户端尝试建立与服务端的连接,这里和第一种方法并无区别。下面看实例:复制代码public void doBeginConnect(IAsyncResult iar){ Socket client=(Socket)iar.AsyncState; //开始与远程主机进行连接 client.BeginConnect(serverIP,13000,requestCallBack,client); Console.WriteLine(“开始与服务器进行连接“);}private void requestCallBack(IAsyncResult iar){ try { //还原原始的TcpClient对象 TcpClient client=(TcpClient)iar.AsyncState; // client.EndConnect(iar); Console.WriteLine(“与服务器{0}连接成功“,client.Client.RemoteEndPoint); } catch(Exception e) { Console.WriteLine(e.ToString()); } finally { }}复制代码  以上是建立连接的两种方法。可根据需要选择使用。3.2 发送与接受数据  在建立了套接字的连接后,就可以服务器端和客户端之间进行数据通信了。异步套接字用BeginSend和EndSend方法来负责数据的发送。注意在调用BeginSend方法前要确保双方都已经建立连接,否则会出异常。下面演示代码:复制代码private static void Send(Socket handler, String data){ // Convert the string data to byte data using ASCII encoding. byte byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);}private static void SendCallback(IAsyncResult ar){ try { // Retrieve the socket from the state object. Socket handler = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = handler.EndSend(ar); Console.WriteLine(“Sent {0} bytes to client.“, bytesSent); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); }}复制代码  接收数据是通过BeginReceive和EndReceive方法:复制代码private static void Receive(Socket client){ try { // Create the state object. StateObject state = new StateObject(); state.workSocket = client; // Begin receiving the data from the remote device. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); }}private static void ReceiveCallback(IAsyncResult ar){ try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int bytesRead = client.EndReceive(ar); if (bytesRead 》 0) { // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // All the data has arrived; put it in response. if (state.sb.Length 》 1) { response = state.sb.ToString(); } // Signal that all bytes have been received. receiveDone.Set(); } } catch (Exception e) { Console.WriteLine(e.ToString()); }}复制代码  上述代码的处理逻辑为:(1)首先处理连接的回调函数里得到的通讯套接字client,接着开始接收数据;(2)当数据发送到缓冲区中,BeginReceive方法试图从buffer数组中读取长度为buffer.length的数据块,并返回接收到的数据量bytesRead。最后接收并打印数据。    除了上述方法外,还可以使用基于NetworkStream相关的异步发送和接收方法,下面是基于NetworkStream相关的异步发送和接收方法的使用介绍。  NetworkStream使用BeginRead和EndRead方法进行读操作,使用BeginWreite和EndWrete方法进行写操作,下面看实例:复制代码static void DataHandle(TcpClient client){ TcpClient tcpClient = client; //使用TcpClient的GetStream方法获取网络流 NetworkStream ns = tcpClient.GetStream(); //检查网络流是否可读 if(ns.CanRead) { //定义缓冲区 byte read = new byte; ns.BeginRead(read,0,read.Length,new AsyncCallback(myReadCallBack),ns); } else { Console.WriteLine(“无法从网络中读取流数据“); }}public static void myReadCallBack(IAsyncResult iar){ NetworkStream ns = (NetworkStream)iar.AsyncState; byte read = new byte; String data = ““; int recv; recv = ns.EndRead(iar); data = String.Concat(data, Encoding.ASCII.GetString(read, 0, recv)); //接收到的消息长度可能大于缓冲区总大小,反复循环直到读完为止 while (ns.DataAvailable) { ns.BeginRead(read, 0, read.Length, new AsyncCallback(myReadCallBack), ns); } //打印 Console.WriteLine(“您收到的信息是“ + data);}复制代码3.3 程序阻塞与异步中的同步问题  .Net里提供了EventWaitHandle类来表示一个线程的同步事件。EventWaitHandle即事件等待句柄,他允许线程通过操作系统互发信号和等待彼此的信号来达到线程同步的目的。这个类有2个子类,分别为AutoRestEevnt(自动重置)和ManualRestEvent(手动重置)。下面是线程同步的几个方法:(1)Rset方法:将事件状态设为非终止状态,导致线程阻塞。这里的线程阻塞是指允许其他需要等待的线程进行阻塞即让含WaitOne()方法的线程阻塞;(2)Set方法:将事件状态设为终止状态,允许一个或多个等待线程继续。该方法发送一个信号给操作系统,让处于等待的某个线程从阻塞状态转换为继续运行,即WaitOne方法的线程不在阻塞;(3)WaitOne方法:阻塞当前线程,直到当前的等待句柄收到信号。此方法将一直使本线程处于阻塞状态直到收到信号为止,即当其他非阻塞进程调用set方法时可以继续执行。复制代码public static void StartListening(){ // Data buffer for incoming data. byte bytes = new Byte; // Establish the local endpoint for the socket. // The DNS name of the computer // running the listener is “host.contoso.com“. //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); //IPAddress ipAddress = ipHostInfo.AddressList; IPAddress ipAddress = IPAddress.Parse(“127.0.0.1“); IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local //endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { // Set the event to nonsignaled state. allDone.Reset(); // Start an asynchronous socket to listen for connections. Console.WriteLine(“Waiting for a connection...“); listener.BeginAccept(new AsyncCallback(AcceptCallback),listener); // Wait until a connection is made before continuing. allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine(“\nPress ENTER to continue...“); Console.Read();}复制代码  上述代码的逻辑为:(1)试用了ManualRestEvent对象创建一个等待句柄,在调用BeginAccept方法前使用Rest方法允许其他线程阻塞;(2)为了防止在连接完成之前对套接字进行读写操作,务必要在BeginAccept方法后调用WaitOne来让线程进入阻塞状态。  当有连接接入后系统会自动调用会调用回调函数,所以当代码执行到回调函数时说明连接已经成功,并在函数的第一句就调用Set方法让处于等待的线程可以继续执行

libevent是怎么把signal集成到事件主循环框架中的

Socket pair就是一个socket对,包含两个socket,一个读socket,一个写socket。工作方式如下图所示:创建一个socket pair并不是复杂的操作,可以参见下面的流程图,清晰起见,其中忽略了一些错误处理和检查。Libevent提供了辅助函数evutil_socketpair()来创建一个socket pair,可以结合上面的创建流程来分析该函数。2 集成到事件主循环——通知event_base Socket pair创建好了,可是libevent的事件主循环还是不知道Signal是否发生了啊,看来我们还差了最后一步,那就是:为socket pair的读socket在libevent的event_base实例上注册一个persist的读事件。 这样当向写socket写入数据时,读socket就会得到通知,触发读事件,从而event_base就能相应的得到通知了。

request timed out 怎么解决

一般情况下不会出现RequestTimedOut,相对来说是TimedOut出现的比较多,RTO是本机网络测试,TO是对服务器的网络测试。如果你确定是RTO,推荐你检查一下网络接口,网线跟路由器和电脑的接口是否有问题。如果连接没问题就去想一下会不会是ARP问题。追问:接口没问题,会不会是路由器或者网卡的问题啊?回答:你如果能正常上网的,那么你本地的硬件问题。我给你以下几种解决办法,你根据自己的实际情况选择相应的处理办法。一、光纤接入:先尝试重启,如果重启后还是由相同问题,那就直接找接入商吧。因为光纤这东西一般人操作不了。二、ADSL接入:A:检查一下电话线的连接是否有问题,如果没问题,那可能就是你的分接线的问题(其它用你宽带账户上网的人在大量占用网络资源)。你可以一根一根拔掉,看看是哪根的问题,再通知对方。如果是这种情况,其实也不推荐你通知对方,如果对方是你的合租伙伴,或者你是房东,甚至你们是家人的话,那就推荐你去营业厅升级宽带了,一般光纤的话不存在类似问题。我家就是4MB光纤的。一般网速都很稳定。B:检查MODEM和路由器、网卡设置,一般MODEM使用默认即可。路由器设置好账号、密码,然后开机自动登陆即可。这种方法很常见的一种错误就是吧ADSLMODEM的IP地址或DNS设置错了,因为ADSL选择自由分配IP地址即可,TCP/IP网关一般也不需要另外去设置。DNS你去营业厅即可获得。C:就像你说的路由器或网卡的问题,推荐不要选用劣质的产品,要记住这类商品是一分钱一分货,如果你的硬件是很好的,直接排除这种可能性。D:网络连接线的问题,网线,你换接口或连接的时候要注意网线内部是否有接线错误。目前国内的两种网线标准:EIA/TIA568A和EIA/TIAT568B,两者本质上没有什么大的区别,只是颜色不同。接下来我对这两种规格的网线进行解析(内部线排序)。EIA/TIA568A:绿白、绿、橙白、蓝、蓝白、橙、褐白、褐。EIA/TIAT568B:橙白、橙、绿白、蓝、蓝白、绿、褐白、褐。目前用的比较多的是EIA/TIAT568B,两机对接需要一端用EIA568A,另一端使用EIA568B。E:【最有可能的一点】如果基本排除是你硬件的问题,那么或许就是软件的问题,你可以对你的系统进行全盘查杀,因为有些病毒和木马也会阻断网络或占用大量网络资源。补充:更正一句话,刚才补充的回答的第一句话:你如果能正常上网的,那么你本地的硬件问题应该不大,但也不完全排除。提问者的感言:谢谢!

css样式中,position元素有几个属性它们之间有什么联系和区别是什么

CSS position 属性通过使用 position 属性,我们可以选择 4 种不同类型的定位,这会影响元素框生成的方式。position 属性值的含义:static元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。relative元素框偏移某个距离。元素仍保持其未定位前的形状,它原本所占的空间仍保留。absolute元素框从文档流完全删除,并相对于其包含块定位。包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,就好像元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。fixed元素框的表现类似于将 position 设置为 absolute,不过其包含块是视窗本身。提示:相对定位实际上被看作普通流定位模型的一部分,因为元素的位置相对于它在普通流中的位置。


声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,谢谢。

上一篇: win7图标(win7桌面图标大小调整)

下一篇: 让孩子自信的28个方法 怎样建立孩子的自信心



推荐阅读