| 关于Socket简单问题 |
| [ 来源:ITWENKU 时间:2006-9-27 11:18:58 | 浏览:183人次
] |
| |
现在我刚刚开始网络编程,对于Socket还不是很熟悉,大家有没有好一点的例子给我参考一下,最好是同步和异步的都有,先谢谢各位了.
同步:
using System; using System.Text; using System.IO; using System.Net; using System.Net.Sockets;
public class GetSocket { private static Socket ConnectSocket(string server, int port) { Socket s = null; IPHostEntry hostEntry = null; // Get host related information. hostEntry = Dns.GetHostEntry(server);
// Loop through the AddressList to obtain the supported AddressFamily. This is to avoid // an exception that occurs when the host IP Address is not compatible with the address family // (typical in the IPv6 case). foreach(IPAddress address in hostEntry.AddressList) { IPEndPoint ipe = new IPEndPoint(address, port); Socket tempSocket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipe);
if(tempSocket.Connected) { s = tempSocket; break; } else { continue; } } return s; }
// This method requests the home page content for the specified server. private static string SocketSendReceive(string server, int port) { string request = "GET / HTTP/1.1\r\nHost: " + server + "\r\nConnection: Close\r\n\r\n"; Byte[] bytesSent = Encoding.ASCII.GetBytes(request); Byte[] bytesReceived = new Byte[256]; // Create a socket connection with the specified server and port. Socket s = ConnectSocket(server, port);
if (s == null) return ("Connection failed"); // Send request to the server. s.Send(bytesSent, bytesSent.Length, 0); // Receive the server home page content. int bytes = 0; string page = "Default HTML page on " + server + ":\r\n";
// The following will block until te page is transmitted. do { bytes = s.Receive(bytesReceived, bytesReceived.Length, 0); page = page + Encoding.ASCII.GetString(bytesReceived, 0, bytes); } while (bytes > 0); return page; } public static void Main(string[] args) { string host; int port = 80;
if (args.Length == 0) // If no server name is passed as argument to this program, // use the current host name as the default. host = Dns.GetHostName(); else host = args[0];
string result = SocketSendReceive(host, port); Console.WriteLine(result); } }
异步: 异步服务器套接字使用 .NET Framework 异步编程模型处理网络服务请求。Socket 类遵循标准 .NET Framework 异步命名模式;例如,同步 Accept 方法对应异步 BeginAccept 和 EndAccept 方法。
异步服务器套接字需要一个开始接受网络连接请求的方法,一个处理连接请求并开始接收网络数据的回调方法以及一个结束接收数据的回调方法。本节将进一步讨论所有这些方法。
在下面的示例中,为开始接受网络连接请求,方法 StartListening 初始化 Socket,然后使用 BeginAccept 方法开始接受新连接。当套接字上接收到新连接请求时,将调用接受回调方法。它负责获取将处理连接的 Socket 实例,并将该 Socket 提交给将处理请求的线程。接受回调方法实现 AsyncCallback 委托;它返回 void,并带一个 IAsyncResult 类型的参数。下面的示例是接受回调方法的外壳程序。
void acceptCallback( IAsyncResult ar) { // Add the callback code here. }
BeginAccept 方法带两个参数:指向接受回调方法的 AsyncCallback 委托和一个用于将状态信息传递给回调方法的对象。在下面的示例中,侦听 Socket 通过 state 参数传递给回调方法。本示例创建一个 AsyncCallback 委托并开始接受网络连接。
listener.BeginAccept( new AsyncCallback(SocketListener.acceptCallback), listener);
异步套接字使用系统线程池中的线程处理传入的连接。一个线程负责接受连接,另一线程用于处理每个传入的连接,还有一个线程负责接收连接数据。这些线程可以是同一个线程,具体取决于线程池所分配的线程。在下面的示例中,System.Threading.ManualResetEvent 类挂起主线程的执行并在执行可以继续时发出信号。
下面的示例显示在本地计算机上创建异步 TCP/IP 套接字并开始接受连接的异步方法。它假定以下内容:存在一个名为 allDone 的全局 ManualResetEvent,该方法是一个名为 SocketListener 的类的成员,以及定义了一个名为 acceptCallback 的回调方法。
public void StartListening() { IPHostEntry ipHostInfo = 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); listener.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。
public void acceptCallback(IAsyncResult ar) { allDone.Set();
Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar);
// Additional code to read data goes here. }
从客户端套接字读取数据需要一个在异步调用之间传递值的状态对象。下面的示例实现一个用于从远程客户端接收字符串的状态对象。它包含以下各项的字段:客户端套接字,用于接收数据的数据缓冲区,以及用于创建客户端发送的数据字符串的 StringBuilder。将这些字段放在该状态对象中,使这些字段的值在多个调用之间得以保留,以便从客户端套接字读取数据。
public class StateObject { public Socket workSocket = null; public const int BufferSize = 1024; public byte[] buffer = new byte[BufferSize]; public StringBuilder sb = new StringBuilder(); }
开始从客户端套接字接收数据的 acceptCallback 方法的此节首先初始化 StateObject 类的一个实例,然后调用 BeginReceive 方法以开始从客户端套接字异步读取数据。
下面的示例显示了完整的 acceptCallback 方法。它假定以下内容:存在一个名为 allDone, 的全局 ManualResetEvent,定义了 StateObject 类,以及在名为 SocketListener 的类中定义了 readCallback 方法。
public static void acceptCallback(IAsyncResult ar) { // Get the socket that handles the client request. Socket listener = (Socket) ar.AsyncState; Socket handler = listener.EndAccept(ar);
// Signal the main thread to continue. allDone.Set();
// Create the state object. StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(AsynchronousSocketListener.readCallback), state); }
需要为异步套接字服务器实现的 final 方法是返回客户端发送的数据的读取回调方法。与接受回调方法一样,读取回调方法也是一个 AsyncCallback 委托。该方法将来自客户端套接字的一个或多个字节读入数据缓冲区,然后再次调用 BeginReceive 方法,直到客户端发送的数据完成为止。从客户端读取整个消息后,在控制台上显示字符串,并关闭处理与客户端的连接的服务器套接字。
下面的示例实现 readCallback 方法。它假定定义了 StateObject 类。
public static void readCallback(IAsyncResult ar) { StateObject state = (StateObject) ar.AsyncState; Socket handler = state.WorkSocket;
// Read data from the client socket. int read = handler.EndReceive(ar);
// Data was read from the client socket. if (read > 0) { state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,read)); handler.BeginReceive(state.buffer,0,StateObject.BufferSize, 0, new AsyncCallback(readCallback), state); } else { if (state.sb.Length > 1) { // All the data has been read from the client; // display it on the console. string content = state.sb.ToString(); Console.WriteLine("Read {0} bytes from socket.\n Data : {1}", content.Length, content); } handler.Close(); } }
摆脱,不要把SDK文档里的东西往上面方,我向要的是实际应用里的实例
把你的邮箱留下,我给你发一份代码.
leishuaiwu@yahoo.com.cn
请发吧
yaopeng117@yahoo.com.cn
什么SDK的东东呀? 我觉得还可以,仔细看了一遍,感觉socket入门了!
BeginReceive代码呢? 没用过异步回调,BeginReceive的参数应该为几个? 把代码贴出来吧,谢谢!
哦,原来是Socket的方法呀,明白了!
|
|
 |
最新更新 |
|