首页 > 编程 > .NET > 正文

使用.NET访问Internet(5) Paul_Ni(原作)(补充)

2024-07-10 12:58:28
字体:
来源:转载
供稿:网友

异步服务器套接字示例


下面的示例程序创建一个接收来自客户端的连接请求的服务器。该服务器是用异步套接字生成的,因此在等待来自客户端的连接时不挂起服务器应用程序的执行。该应用程序接收来自客户端的字符串,在控制台显示该字符串,然后将该字符串回显到客户端。来自客户端的字符串必须包含字符串“<eof>”,以发出表示消息结尾的信号。
 [c#]
using system;
using system.net;
using system.net.sockets;
using system.text;
using system.threading;
 
// state object for reading client data asynchronously
public class stateobject {
   public socket worksocket = null;       // client  socket.
   public const int buffersize = 1024;       // size of receive buffer.
   public byte[] buffer = new byte[buffersize]; // receive buffer.
   public stringbuilder sb = new stringbuilder();  // received data string.
}
 
public class asynchronoussocketlistener {
   
   // incoming data from client.
   public static string data = null;
 
   // thread signal.
   public static manualresetevent alldone = new manualresetevent(false);
 
   public asynchronoussocketlistener() {
   }
 
   public static void startlistening() {
      // data buffer for incoming data.
      byte[] bytes = new byte[1024];
 
      // 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[0];
      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("/nhit enter to continue...");
      console.read();
      
   }
 
   public static void acceptcallback(iasyncresult ar) {
      // signal the main thread to continue.
      alldone.set();
 
      // get the socket that handles the client request.
      socket listener = (socket) ar.asyncstate;
      socket handler = listener.endaccept(ar);
 
      // create the state object.
      stateobject state = new stateobject();
      state.worksocket = handler;
      handler.beginreceive( state.buffer, 0, stateobject.buffersize, 0,
         new asynccallback(readcallback), state);
   }
 
   public static void readcallback(iasyncresult ar) {
      string content = string.empty;
      
      // retrieve the state object and the handler socket
      // from the async state object.
      stateobject state = (stateobject) ar.asyncstate;
      socket handler = state.worksocket;
 
      // read data from the client socket. 
      int bytesread = handler.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));
 
         // check for end-of-file tag. if  it is not there, read 
         // more data.
         content = state.sb.tostring();
         if (content.indexof("<eof>") > -1) {
            // all the data has been read from the 
            // client. display it on the console.
            console.writeline("read {0} bytes from socket. /n data : {1}",
               content.length, content );
            // echo the data back to the client.
            send(handler, content);
         } else {
            // not all data received. get more.
            handler.beginreceive(state.buffer, 0, stateobject.buffersize, 0,
            new asynccallback(readcallback), state);
         }
      }
   }
   
   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());
      }
   }
 
 
   public static int main(string[] args) {
      startlistening();
      return 0;
   }
}

使用 net 类的最佳做法


下列建议将帮助您最有效地使用 system.net 中包含的类:
  • 尽可能使用 webrequest 和 webresponse 而不是类型转换为子代类。使用 webrequestwebresponse 的应用程序可以利用新的 internet 协议,而不需要进行大范围的代码更改。
  • 当使用 system.net 类编写运行在服务器上的 asp.net 应用程序时,从性能的角度来看,使用 getresponse 和 getresponsestream 的异步方法通常更好。
  • 对 internet 资源打开的连接数可能对网络性能和吞吐量有显著的影响。默认情况下,system.net 对每个主机的每个应用程序使用两个连接。设置应用程序的 servicepoint 中的 connectionlimit 属性可为特定主机增加此数目。设置 servicepointmanager.defaultpersistentconnectionlimit 属性可为所有主机增加此默认值。
  • 当编写套接字级别的协议时,请尽可能尝试使用 tcpclient 或 udpclient,而不是直接向 socket 中写。这两个客户端类封装 tcp 和 udp 套接字的创建,而不需要您处理连接的细节。
  • 当访问要求凭据的站点时,请使用 credentialcache 类创建凭据的缓存而不要对每个请求都提供它们。credentialcache 类搜索缓存以查找要提供给请求的适当凭据,从而使您不必根据统一资源定位器来创建和提供凭据。

总结


    上面是vs.net中.net访问internet的一些基本概念和代码示例(包括访问internet的各种方法和步骤),给大家参考一下。有任何建议请mail我 [email protected]([email protected])。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表