使用.NET访问Internet(4) Paul

使用异步客户端套接字

异步客户端套接字在等待网络操作完成时不挂起应用程序。相反,它使用标准 .NET 框架异步编程模型在一个线程上处理网络连接,而应用程序继续在原始线程上运行。异步套接字适用于大量使用网络或不能等待网络操作完成才能继续的应用程序。
Socket 类遵循异步方法的 .NET 框架命名模式;例如,同步 Receive 方法对应异步 BeginReceive 和 EndReceive 方法。
异步操作要求回调方法返回操作结果。如果应用程序不需要知道结果,则不需要任何回调方法。本节中的代码示例阐释如何使用某个方法开始与网络设备的连接并使用回调方法结束连接,如何使用某个方法开始发送数据并使用回调方法完成发送,以及如何使用某个方法开始接收数据并使用回调方法结束接收数据。
异步套接字使用多个系统线程池中的线程处理网络连接。一个线程负责初始化数据的发送或接收;其他线程完成与网络设备的连接并发送或接收数据。在下列示例中,System.Threading.ManualResetEvent 类的实例用于挂起主线程的执行并在执行可以继续时发出信号。
在下面的示例中,为了将异步套接字连接到网络设备,Connect 方法初始化 Socket 实例,然后调用 BeginConnect 方法,传递表示网络设备的远程终结点、连接回调方法以及状态对象(即客户端 Socket 实例,用于在异步调用之间传递状态信息)。该示例实现 Connect 方法以将指定的 Socket 实例连接到指定的终结点。它假定存在一个名为 connectDone 的全局 ManualResetEvent

 [C#]
public static void Connect(EndPoint remoteEP, Socket client) {
  client.BeginConnect(remoteEP, 
    new AsyncCallback(ConnectCallback), client );
 
  connectDone.WaitOne();
}

连接回调方法 ConnectCallback 实现 AsyncCallback 委托。它在远程设备可用时连接到远程设备,然后通过设置 ManualResetEvent connectDone 向应用程序线程发出连接完成的信号。下面的代码实现 ConnectCallback 方法。

 [C#]
private static void ConnectCallback(IAsyncResult ar) {
  try {
    // Retrieve the socket from the state object.
    Socket client = (Socket) ar.AsyncState;
 
    // Complete the connection.
    client.EndConnect(ar);
 
    Console.WriteLine("Socket connected to {0}",
      client.RemoteEndPoint.ToString());
 
    // Signal that the connection has been made.
    connectDone.Set();
  } catch (Exception e) {
    Console.WriteLine(e.ToString());
  }
}

Send 示例方法以 ASCII 格式对指定的字符串数据进行编码,并将其异步发送到指定的套接字所表示的网络设备。下面的示例实现 Send 方法。

 [C#]
private static void Send(Socket client, 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.
  client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,
    new AsyncCallback(SendCallback), client);
}

发送回调方法 SendCallback 实现 AsyncCallback 委托。它在网络设备准备接收时发送数据。下面的示例显示 SendCallback 方法的实现。它假定存在一个名为 sendDone 的全局 ManualResetEvent 实例。

 [C#]
private static void SendCallback(IAsyncResult ar) {
  try {
    // Retrieve the socket from the state object.
    Socket client = (Socket) ar.AsyncState;
 
    // Complete sending the data to the remote device.
    int bytesSent = client.EndSend(ar);
    Console.WriteLine("Sent {0} bytes to server.", bytesSent);
 
    // Signal that all bytes have been sent.
    sendDone.Set();
  } catch (Exception e) {
    Console.WriteLine(e.ToString());
  }
}

从客户端套接字读取数据需要一个在异步调用之间传递值的状态对象。下面的类是用于从客户端套接字接收数据的示例状态对象。它包含以下各项的字段:客户端套接字,用于接收数据的缓冲区,以及用于保存传入数据字符串的 StringBuilder。将这些字段放在该状态对象中,使这些字段的值在多个调用之间得以保留,以便从客户端套接字读取数据。

 [C#]
public class StateObject {
  public Socket workSocket = null;              // Client socket.
  public const int BufferSize = 256;            // Size of receive buffer.
  public byte[] buffer = new byte[BufferSize];  // Receive buffer.
  public StringBuilder sb = new StringBuilder();// Received data string.
}

Receive 方法示例设置状态对象,然后调用 BeginReceive 方法从客户端套接字异步读取数据。下面的示例实现 Receive 方法。

 [C#]
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());
  }
}

接收回调方法 ReceiveCallback 实现 AsyncCallback 委托。它接收来自网络设备的数据并生成消息字符串。它将来自网络的一个或多个数据字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。从客户端读取所有数据后,ReceiveCallback 通过设置 ManualResetEvent sendDone 向应用程序线程发出数据完成的信号。
下面的示例代码实现 ReceiveCallback 方法。它假定存在一个名为 response 的全局字符串(该字符串保存接收的字符串)和一个名为 receiveDone 的全局 ManualResetEvent 实例。服务器必须正常关闭客户端套接字以结束网络会话。

 [C#]
private static void ReceiveCallback( IAsyncResult ar ) {
  try {
    // Retrieve the state object and the client socket 
    // from the async 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());
  }
}

用套接字进行侦听

侦听器或服务器套接字在网络上打开一个端口,然后等待客户端连接到该端口。尽管存在其他网络地址族和协议,但本示例说明如何为 TCP/IP 网络创建远程服务。
TCP/IP 服务的唯一地址是这样定义的:将主机的 IP 地址与服务的端口号组合,以便为服务创建终结点。Dns 类提供的方法返回有关本地网络设备支持的网络地址的信息。当本地网络设备有多个网络地址时,或者当本地系统支持多个网络设备时,Dns 类返回有关所有网络地址的信息,应用程序必须为服务选择正确的地址。Internet 分配号码机构 (Internet Assigned Numbers Authority, IANA) 定义公共服务的端口号(有关更多信息,请访问 http://www.iana.org/assignments/port-numbers)。其他服务可以具有 1,024 到 65,535 范围内的注册端口号。
下面的代码示例通过将 Dns 为主机返回的第一个 IP 地址与从注册端口号范围内选择的端口号组合,为服务器创建 IPEndPoint。

 [C#]
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

确定本地终结点后,必须使用 Bind 方法将 Socket 与该终结点关联,并使用 Listen 方法设置 Socket 在该终结点上侦听。如果特定的地址和端口组合已经被使用,则 Bind 将引发异常。下面的示例阐释如何将 SocketIPEndPoint 关联。

 [C#]
listener.Bind(localEndPoint);
listener.Listen(100);

Listen 方法带单个参数,该参数指定在向连接客户端返回服务器忙错误之前允许的 Socket 挂起连接数。在本示例中,在向第 101 个客户端返回服务器忙响应之前,最多可以在连接队列中放置 100 个客户端。

使用同步服务器套接字

同步服务器套接字挂起应用程序的执行,直到套接字上接收到连接请求。同步服务器套接字不适用于在操作中大量使用网络的应用程序,但它们可能适用于简单的网络应用程序。
使用 Bind 和 Listen 方法设置 Socket 以在终结点上侦听之后,Socket 就可以随时使用 Accept 方法接受传入的连接请求了。应用程序被挂起,直到调用 Accept 方法时接收到连接请求。
接收到连接请求时,Accept 返回一个与连接客户端关联的新 Socket 实例。下面的示例读取客户端数据,在控制台上显示该数据,然后将该数据回显到客户端。Socket 不指定任何消息协议,因此字符串“<EOF>”标记消息数据的结尾。它假定名为 listener 的 Socket 实例已初始化并绑定到终结点。

 [C#]
Console.WriteLine("Waiting for a connection...");
Socket handler = listener.Accept();
String data = null;
 
while (true) {
  bytes = new byte[1024];
  int bytesRec = handler.Receive(bytes);
  data += Encoding.ASCII.GetString(bytes,0,bytesRec);
  if (data.IndexOf("<EOF>") > -1) {
    break;
  }
}
 
Console.WriteLine( "Text received : {0}", data);
 
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();

使用异步服务器套接字

异步服务器套接字使用 .NET 框架异步编程模型处理网络服务请求。Socket 类遵循标准 .NET 异步命名模式;例如,同步 Accept 方法对应异步 BeginAccept 和 EndAccept 方法。
异步服务器套接字需要一个开始接受网络连接请求的方法,一个处理连接请求并开始接收网络数据的回调方法以及一个结束接收数据的回调方法。本节将进一步讨论所有这些方法。
在下面的示例中,为开始接受网络连接请求,方法 StartListening 初始化 Socket,然后使用 BeginAccept 方法开始接受新连接。当套接字上接收到新连接请求时调用接受回调方法。它负责获取将处理连接的 Socket 实例,并将 Socket 提交给将处理请求的线程。接受回调方法实现 AsyncCallback 委托;它返回 void,并带一个 IAsyncResult 类型的参数。下面的示例是接受回调方法的外壳程序。

 [C#]
void acceptCallback( IAsyncResult ar) {
  //Add the callback code here.
}

BeginAccept 方法带两个参数:指向接受回调方法的 AsyncCallback 委托和一个用于将状态信息传递给回调方法的对象。在下面的示例中,侦听 Socket 通过状态参数传递给回调方法。本示例创建一个 AsyncCallback 委托并开始接受网络连接。

 [C#]
listener.BeginAccept(
  new AsyncCallback(SocketListener.acceptCallback), 
  listener);

异步套接字使用系统线程池中的线程处理传入的连接。一个线程负责接受连接,另一线程用于处理每个传入的连接,还有一个线程负责接收连接数据。这些线程可以是同一个线程,具体取决于线程池所分配的线程。在下面的示例中,System.Threading.ManualResetEvent 类挂起主线程的执行并在执行可以继续时发出信号。
下面的示例显示在本地计算机上创建异步 TCP/IP 套接字并开始接受连接的异步方法。它假定以下内容:存在一个名为 allDone 的全局 ManualResetEvent 实例,该方法是名为 SocketListener 类的成员,以及定义了一个名为 acceptCallback 的回调方法。

 [C#]
public void StartListening() {
  IPHostEntry ipHostInfo = new Dns.Resolve(Dns.GetHostName());
  IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList[0],11000);
 
  Console.WriteLine("Local address and port : {0}",localEP.ToString());
 
  Socket listener = new Socket( localEP.Address.AddressFamily,
    SocketType.Stream, ProtocolType.Tcp );
 
  try {
    listener.Bind(localEP);
    s.Listen(10);
 
    while (true) {
      allDone.Reset();
 
      Console.WriteLine("Waiting for a connection...");
      listener.BeginAccept(
        new AsyncCallback(SocketListener.acceptCallback), 
        listener );
 
      allDone.WaitOne();
    }
  } catch (Exception e) {
    Console.WriteLine(e.ToString());
  }
 
  Console.WriteLine( "Closing the listener...");
}

接受回调方法(即前例中的 acceptCallback)负责向主应用程序发出信号,让它继续执行处理、建立与客户端的连接并开始异步读取客户端数据。下面的示例是 acceptCallback 方法实现的第一部分。该方法的此节向主应用程序线程发出信号,让它继续处理并建立与客户端的连接。它假定存在一个名为 allDone 的全局 ManualResetEvent 实例。

 [C#]
public void acceptCallback(IAsyncResult ac) {
  allDone.Set();
 
  Socket listener = (Socket) ar.AsyncState;
  Socket handler = listener.EndAccept(ar);
 
  // Additional code to read data goes here.  
}

从客户端套接字读取数据需要一个在异步调用之间传递值的状态对象。下面的示例实现一个用于从远程客户端接收字符串的状态对象。它包含以下各项的字段:客户端套接字,用于接收数据的数据缓冲区,以及用于创建客户端发送的数据字符串的 StringBuilder。将这些字段放在该状态对象中,使这些字段的值在多个调用之间得以保留,以便从客户端套接字读取数据。

 [C#]
public class StateObject {
  public Socket workSocket = null;
  public const int BufferSize = 1024;
  public byte[] buffer = new byte[BufferSize];
  public StringBuilder sb = new StringBuilder();

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c#
, socket
, 数据库连接 c#
, 数据
, 方法
, 套接字
, 网络的异步访问
, c# socket 网络编程
, c#接收返回值
示例
paul jaminet、无internet访问、无internet访问权限、无internet访问感叹号、网络无internet访问,以便于您获取更多的相关知识。

时间: 2025-01-29 23:45:15

使用.NET访问Internet(4) Paul的相关文章

使用.NET访问 Internet(1) Paul

Microsoft .NET 框架提供 Internet 服务的分层的.可扩展的和托管的实现,您可以将这些 Internet 服务快速而轻松地集成到您的应用程序中.您的应用程序可建立在可插接式协议的基础之上以便自动利用新的 Internet 协议,或者它们可以使用 Windows 套接字接口的托管实现来使用套接字级别上的网络. 介绍可插接式协议 Microsoft .NET 框架提供分层的.可扩展的和托管的 Internet 服务实现,您可以将它们快速而轻松地集成到您的应用程序中.System.

使用.NET访问 Internet(3) Paul

使用.NET访问 Internet(3) Paul_Ni(原作) 作者:中国资讯网 来源:zixuen.com 加入时间:2005-5-12 www.zixuen.com 使用 TCP 服务 TCPClient 类使用 TCP 从 Internet 资源请求数据.TcpClient 的方法和属性提取某个 Socket 实例的创建细节,该实例用于通过 TCP 请求和接收数据.由于到远程设备的连接表示为流,因此可以使用 .NET 框架流处理技术读取和写入数据.TCP 协议建立与远程终结点的连接,然后

使用.NET访问 Internet(2) Paul

实现异步请求 System.Net 类使用 .NET 框架的标准异步编程模型对 Internet 资源进行异步访问.WebRequest 类的 BeginGetResponse 和 EndGetResponse 方法分别启动和完成对 Internet 资源的异步请求.注意 在异步回调方法中使用同步调用可能会导致严重的性能降低.通过 WebRequest 及其子代实现的 Internet 请求必须使用 Stream.BeginRead 读取由 WebResponse.GetResponseStre

使用.NET访问Internet(5) Paul

同步客户端套接字示例 下面的示例程序创建一个连接到服务器的客户端.该客户端是用同步套接字生成的,因此挂起客户端应用程序的执行,直到服务器返回响应为止.该应用程序将字符串发送到服务器,然后在控制台显示该服务器返回的字符串. [C#] using System; using System.Net; using System.Net.Sockets; using System.Text; public class SynchronousSocketClient {   public static vo

Android简明开发教程二十一:访问Internet 绘制在线地图

在例子Android简明开发教程十七:Dialog 显示图像 中我们留了一个例子DrawMap()没有实现,这个例子显示在线地图,目前大部分地图服务器都是将地图以图片存储以提高响应速 度. 一般大小为256X256个像素.具体可以参见离线地图下载方法解析. 比如: URL http://www.mapdigit.com/guidebeemap/maptile.php?type=MICROSOFTMAP&x=7&y=4&z=14 显示: 下面的例子访问Internet下载地图图片,并

您可能需要与该网络的internet服务提供商(isp)签署协议才能获得访问 internet的权限解决

 今天开机网络连接出现感叹号,但网络连接正常,点了疑难解答,提示"您可能需要与该网络的 internet 服务提供商(isp)签署协议才能获得访问 internet 的权限", 经过研究问题解决,现把方法共享下: 解决方案: 开始---运行----regedit. 打开后 1. 找到注册表键值HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesNlaSvcParametersInternet 2. 双击HKEY_LOCAL_MACHINES

无线网络无法访问Internet

  无线网络连接正常,但是无法正常连接到Internet. 这样的情况可能是没有得到有效的IP地址,可以对无线网卡的地址进行检查.在一般情况下,无线网卡通过DHCP的方式获取IP地址和DNS服务器的地址.可以选择"开始"→"运行",然后输入cmd,单击"确定",就可以打开"命令提示符",再输入ipconfig/all,查看返回的结果.如果IP地址.网关和DNS都没有错误,却仍然无法访问Internet,就说明网关有问题. 检查

可以访问Internet无法访问其他电脑

  电脑在使用的时候可以正常访问Internet,也可以访问服务器,但是却无法访问其他电脑. 如果电脑在使用WINS解析,就有可能是由于WINS服务器的地址设置错误造成的.然后对网关的设置进行检查,如果双方属于不同的子网,网关的设置错误,则就不能看到其他工作站.还可以对子网掩码设置进行检查.

请教个问题,在VPC中,同一个subnet下,如何设置其它的instance通过同一个subnet下的某个NAT instance来访问internet?

问题描述 请教个问题,在VPC中,同一个subnet下,如何设置其它的instance通过同一个subnet下的某个NATinstance来访问internet? 解决方案 解决方案二:在VPC中有一个叫routetable的东西可用设置你想要的任何形式的路由.你只需要将subnet的route设置为从NATinstance走就可以了