注銷

          注銷

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            112 隨筆 :: 7 文章 :: 18 評(píng)論 :: 0 Trackbacks

          使用異步客戶端套接字

          異步客戶端套接字在等待網(wǎng)絡(luò)操作完成時(shí)不掛起應(yīng)用程序。相反,它使用標(biāo)準(zhǔn) .NET 框架異步編程模型在一個(gè)線程上處理網(wǎng)絡(luò)連接,而應(yīng)用程序繼續(xù)在原始線程上運(yùn)行。異步套接字適用于大量使用網(wǎng)絡(luò)或不能等待網(wǎng)絡(luò)操作完成才能繼續(xù)的應(yīng)用程序。

          Socket 類遵循異步方法的 .NET 框架命名模式;例如,同步 Receive 方法對(duì)應(yīng)異步 BeginReceive 和 EndReceive 方法。

          異步操作要求回調(diào)方法返回操作結(jié)果。如果應(yīng)用程序不需要知道結(jié)果,則不需要任何回調(diào)方法。本節(jié)中的代碼示例闡釋如何使用某個(gè)方法開(kāi)始與網(wǎng)絡(luò)設(shè)備的連接并使用回調(diào)方法結(jié)束連接,如何使用某個(gè)方法開(kāi)始發(fā)送數(shù)據(jù)并使用回調(diào)方法完成發(fā)送,以及如何使用某個(gè)方法開(kāi)始接收數(shù)據(jù)并使用回調(diào)方法結(jié)束接收數(shù)據(jù)。

          異步套接字使用多個(gè)系統(tǒng)線程池中的線程處理網(wǎng)絡(luò)連接。一個(gè)線程負(fù)責(zé)初始化數(shù)據(jù)的發(fā)送或接收;其他線程完成與網(wǎng)絡(luò)設(shè)備的連接并發(fā)送或接收數(shù)據(jù)。在下列示例中,System.Threading.ManualResetEvent 類的實(shí)例用于掛起主線程的執(zhí)行并在執(zhí)行可以繼續(xù)時(shí)發(fā)出信號(hào)。

          在下面的示例中,為了將異步套接字連接到網(wǎng)絡(luò)設(shè)備,Connect 方法初始化 Socket 實(shí)例,然后調(diào)用 BeginConnect 方法,傳遞表示網(wǎng)絡(luò)設(shè)備的遠(yuǎn)程終結(jié)點(diǎn)、連接回調(diào)方法以及狀態(tài)對(duì)象(即客戶端 Socket 實(shí)例,用于在異步調(diào)用之間傳遞狀態(tài)信息)。該示例實(shí)現(xiàn) Connect 方法以將指定的 Socket 實(shí)例連接到指定的終結(jié)點(diǎn)。它假定存在一個(gè)名為 connectDone 的全局 ManualResetEvent

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

          連接回調(diào)方法 ConnectCallback 實(shí)現(xiàn) AsyncCallback 委托。它在遠(yuǎn)程設(shè)備可用時(shí)連接到遠(yuǎn)程設(shè)備,然后通過(guò)設(shè)置 ManualResetEvent connectDone 向應(yīng)用程序線程發(fā)出連接完成的信號(hào)。下面的代碼實(shí)現(xiàn) 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 格式對(duì)指定的字符串?dāng)?shù)據(jù)進(jìn)行編碼,并將其異步發(fā)送到指定的套接字所表示的網(wǎng)絡(luò)設(shè)備。下面的示例實(shí)現(xiàn) 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);
          }

          發(fā)送回調(diào)方法 SendCallback 實(shí)現(xiàn) AsyncCallback 委托。它在網(wǎng)絡(luò)設(shè)備準(zhǔn)備接收時(shí)發(fā)送數(shù)據(jù)。下面的示例顯示 SendCallback 方法的實(shí)現(xiàn)。它假定存在一個(gè)名為 sendDone 的全局 ManualResetEvent 實(shí)例。

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

          從客戶端套接字讀取數(shù)據(jù)需要一個(gè)在異步調(diào)用之間傳遞值的狀態(tài)對(duì)象。下面的類是用于從客戶端套接字接收數(shù)據(jù)的示例狀態(tài)對(duì)象。它包含以下各項(xiàng)的字段:客戶端套接字,用于接收數(shù)據(jù)的緩沖區(qū),以及用于保存?zhèn)魅霐?shù)據(jù)字符串的 StringBuilder。將這些字段放在該狀態(tài)對(duì)象中,使這些字段的值在多個(gè)調(diào)用之間得以保留,以便從客戶端套接字讀取數(shù)據(jù)。

           [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 方法示例設(shè)置狀態(tài)對(duì)象,然后調(diào)用 BeginReceive 方法從客戶端套接字異步讀取數(shù)據(jù)。下面的示例實(shí)現(xiàn) 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());
           }
          }

          接收回調(diào)方法 ReceiveCallback 實(shí)現(xiàn) AsyncCallback 委托。它接收來(lái)自網(wǎng)絡(luò)設(shè)備的數(shù)據(jù)并生成消息字符串。它將來(lái)自網(wǎng)絡(luò)的一個(gè)或多個(gè)數(shù)據(jù)字節(jié)讀入數(shù)據(jù)緩沖區(qū),然后再次調(diào)用 BeginReceive 方法,直到客戶端發(fā)送的數(shù)據(jù)完成為止。從客戶端讀取所有數(shù)據(jù)后,ReceiveCallback 通過(guò)設(shè)置 ManualResetEvent sendDone 向應(yīng)用程序線程發(fā)出數(shù)據(jù)完成的信號(hào)。

          下面的示例代碼實(shí)現(xiàn) ReceiveCallback 方法。它假定存在一個(gè)名為 response 的全局字符串(該字符串保存接收的字符串)和一個(gè)名為 receiveDone 的全局 ManualResetEvent 實(shí)例。服務(wù)器必須正常關(guān)閉客戶端套接字以結(jié)束網(wǎng)絡(luò)會(huì)話。

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

          用套接字進(jìn)行偵聽(tīng)

          偵聽(tīng)器或服務(wù)器套接字在網(wǎng)絡(luò)上打開(kāi)一個(gè)端口,然后等待客戶端連接到該端口。盡管存在其他網(wǎng)絡(luò)地址族和協(xié)議,但本示例說(shuō)明如何為 TCP/IP 網(wǎng)絡(luò)創(chuàng)建遠(yuǎn)程服務(wù)。

          TCP/IP 服務(wù)的唯一地址是這樣定義的:將主機(jī)的 IP 地址與服務(wù)的端口號(hào)組合,以便為服務(wù)創(chuàng)建終結(jié)點(diǎn)。Dns 類提供的方法返回有關(guān)本地網(wǎng)絡(luò)設(shè)備支持的網(wǎng)絡(luò)地址的信息。當(dāng)本地網(wǎng)絡(luò)設(shè)備有多個(gè)網(wǎng)絡(luò)地址時(shí),或者當(dāng)本地系統(tǒng)支持多個(gè)網(wǎng)絡(luò)設(shè)備時(shí),Dns 類返回有關(guān)所有網(wǎng)絡(luò)地址的信息,應(yīng)用程序必須為服務(wù)選擇正確的地址。Internet 分配號(hào)碼機(jī)構(gòu) (Internet Assigned Numbers Authority, IANA) 定義公共服務(wù)的端口號(hào)(有關(guān)更多信息,請(qǐng)?jiān)L問(wèn) http://www.iana.org/assignments/port-numbers)。其他服務(wù)可以具有 1,024 到 65,535 范圍內(nèi)的注冊(cè)端口號(hào)。

          下面的代碼示例通過(guò)將 Dns 為主機(jī)返回的第一個(gè) IP 地址與從注冊(cè)端口號(hào)范圍內(nèi)選擇的端口號(hào)組合,為服務(wù)器創(chuàng)建 IPEndPoint。

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

          確定本地終結(jié)點(diǎn)后,必須使用 Bind 方法將 Socket 與該終結(jié)點(diǎn)關(guān)聯(lián),并使用 Listen 方法設(shè)置 Socket 在該終結(jié)點(diǎn)上偵聽(tīng)。如果特定的地址和端口組合已經(jīng)被使用,則 Bind 將引發(fā)異常。下面的示例闡釋如何將 SocketIPEndPoint 關(guān)聯(lián)。

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

          Listen 方法帶單個(gè)參數(shù),該參數(shù)指定在向連接客戶端返回服務(wù)器忙錯(cuò)誤之前允許的 Socket 掛起連接數(shù)。在本示例中,在向第 101 個(gè)客戶端返回服務(wù)器忙響應(yīng)之前,最多可以在連接隊(duì)列中放置 100 個(gè)客戶端。

          使用同步服務(wù)器套接字

          同步服務(wù)器套接字掛起應(yīng)用程序的執(zhí)行,直到套接字上接收到連接請(qǐng)求。同步服務(wù)器套接字不適用于在操作中大量使用網(wǎng)絡(luò)的應(yīng)用程序,但它們可能適用于簡(jiǎn)單的網(wǎng)絡(luò)應(yīng)用程序。

          使用 Bind 和 Listen 方法設(shè)置 Socket 以在終結(jié)點(diǎn)上偵聽(tīng)之后,Socket 就可以隨時(shí)使用 Accept 方法接受傳入的連接請(qǐng)求了。應(yīng)用程序被掛起,直到調(diào)用 Accept 方法時(shí)接收到連接請(qǐng)求。

          接收到連接請(qǐng)求時(shí),Accept 返回一個(gè)與連接客戶端關(guān)聯(lián)的新 Socket 實(shí)例。下面的示例讀取客戶端數(shù)據(jù),在控制臺(tái)上顯示該數(shù)據(jù),然后將該數(shù)據(jù)回顯到客戶端。Socket 不指定任何消息協(xié)議,因此字符串“<EOF>”標(biāo)記消息數(shù)據(jù)的結(jié)尾。它假定名為 listener Socket 實(shí)例已初始化并綁定到終結(jié)點(diǎn)。

           [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();

          使用異步服務(wù)器套接字

          異步服務(wù)器套接字使用 .NET 框架異步編程模型處理網(wǎng)絡(luò)服務(wù)請(qǐng)求。Socket 類遵循標(biāo)準(zhǔn) .NET 異步命名模式;例如,同步 Accept 方法對(duì)應(yīng)異步 BeginAccept 和 EndAccept 方法。

          異步服務(wù)器套接字需要一個(gè)開(kāi)始接受網(wǎng)絡(luò)連接請(qǐng)求的方法,一個(gè)處理連接請(qǐng)求并開(kāi)始接收網(wǎng)絡(luò)數(shù)據(jù)的回調(diào)方法以及一個(gè)結(jié)束接收數(shù)據(jù)的回調(diào)方法。本節(jié)將進(jìn)一步討論所有這些方法。

          在下面的示例中,為開(kāi)始接受網(wǎng)絡(luò)連接請(qǐng)求,方法 StartListening 初始化 Socket,然后使用 BeginAccept 方法開(kāi)始接受新連接。當(dāng)套接字上接收到新連接請(qǐng)求時(shí)調(diào)用接受回調(diào)方法。它負(fù)責(zé)獲取將處理連接的 Socket 實(shí)例,并將 Socket 提交給將處理請(qǐng)求的線程。接受回調(diào)方法實(shí)現(xiàn) AsyncCallback 委托;它返回 void,并帶一個(gè) IAsyncResult 類型的參數(shù)。下面的示例是接受回調(diào)方法的外殼程序。

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

          BeginAccept 方法帶兩個(gè)參數(shù):指向接受回調(diào)方法的 AsyncCallback 委托和一個(gè)用于將狀態(tài)信息傳遞給回調(diào)方法的對(duì)象。在下面的示例中,偵聽(tīng) Socket 通過(guò)狀態(tài)參數(shù)傳遞給回調(diào)方法。本示例創(chuàng)建一個(gè) AsyncCallback 委托并開(kāi)始接受網(wǎng)絡(luò)連接。

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

          異步套接字使用系統(tǒng)線程池中的線程處理傳入的連接。一個(gè)線程負(fù)責(zé)接受連接,另一線程用于處理每個(gè)傳入的連接,還有一個(gè)線程負(fù)責(zé)接收連接數(shù)據(jù)。這些線程可以是同一個(gè)線程,具體取決于線程池所分配的線程。在下面的示例中,System.Threading.ManualResetEvent 類掛起主線程的執(zhí)行并在執(zhí)行可以繼續(xù)時(shí)發(fā)出信號(hào)。

          下面的示例顯示在本地計(jì)算機(jī)上創(chuàng)建異步 TCP/IP 套接字并開(kāi)始接受連接的異步方法。它假定以下內(nèi)容:存在一個(gè)名為 allDone 的全局 ManualResetEvent 實(shí)例,該方法是名為 SocketListener 類的成員,以及定義了一個(gè)名為 acceptCallback 的回調(diào)方法。

           [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...");
          }

          接受回調(diào)方法(即前例中的 acceptCallback)負(fù)責(zé)向主應(yīng)用程序發(fā)出信號(hào),讓它繼續(xù)執(zhí)行處理、建立與客戶端的連接并開(kāi)始異步讀取客戶端數(shù)據(jù)。下面的示例是 acceptCallback 方法實(shí)現(xiàn)的第一部分。該方法的此節(jié)向主應(yīng)用程序線程發(fā)出信號(hào),讓它繼續(xù)處理并建立與客戶端的連接。它假定存在一個(gè)名為 allDone 的全局 ManualResetEvent 實(shí)例。

           [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. 
          }

          從客戶端套接字讀取數(shù)據(jù)需要一個(gè)在異步調(diào)用之間傳遞值的狀態(tài)對(duì)象。下面的示例實(shí)現(xiàn)一個(gè)用于從遠(yuǎn)程客戶端接收字符串的狀態(tài)對(duì)象。它包含以下各項(xiàng)的字段:客戶端套接字,用于接收數(shù)據(jù)的數(shù)據(jù)緩沖區(qū),以及用于創(chuàng)建客戶端發(fā)送的數(shù)據(jù)字符串的 StringBuilder。將這些字段放在該狀態(tài)對(duì)象中,使這些字段的值在多個(gè)調(diào)用之間得以保留,以便從客戶端套接字讀取數(shù)據(jù)。

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

          開(kāi)始從客戶端套接字接收數(shù)據(jù)的 acceptCallback 方法的此節(jié)首先初始化 StateObject 類的一個(gè)實(shí)例,然后調(diào)用 BeginReceive 方法以開(kāi)始從客戶端套接字異步讀取數(shù)據(jù)。

          下面的示例顯示了完整的 acceptCallback 方法。它假定以下內(nèi)容:存在一個(gè)名為 allDoneManualResetEvent 實(shí)例,定義了 StateObject 類,以及在名為 SocketListener 的類中定義了 readCallback 方法。

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

          需要為異步套接字服務(wù)器實(shí)現(xiàn)的 final 方法是返回客戶端發(fā)送的數(shù)據(jù)的讀取回調(diào)方法。與接受回調(diào)方法一樣,讀取回調(diào)方法也是一個(gè) AsyncCallback 委托。該方法將來(lái)自客戶端套接字的一個(gè)或多個(gè)字節(jié)讀入數(shù)據(jù)緩沖區(qū),然后再次調(diào)用 BeginReceive 方法,直到客戶端發(fā)送的數(shù)據(jù)完成為止。從客戶端讀取整個(gè)消息后,在控制臺(tái)上顯示字符串,并關(guān)閉處理與客戶端的連接的服務(wù)器套接字。

          下面的示例實(shí)現(xiàn) readCallback 方法。它假定定義了 StateObject 類。

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

          同步客戶端套接字示例

          下面的示例程序創(chuàng)建一個(gè)連接到服務(wù)器的客戶端。該客戶端是用同步套接字生成的,因此掛起客戶端應(yīng)用程序的執(zhí)行,直到服務(wù)器返回響應(yīng)為止。該應(yīng)用程序?qū)⒆址l(fā)送到服務(wù)器,然后在控制臺(tái)顯示該服務(wù)器返回的字符串。

           [C#]
          using System;
          using System.Net;
          using System.Net.Sockets;
          using System.Text;
           
          public class SynchronousSocketClient {
           
           public static void StartClient() {
              // Data buffer for incoming data.
              byte[] bytes = new byte[1024];
           
              // Connect to a remote device.
              try {
                // Establish the remote endpoint for the socket.
                //    The name of the
                //   remote device is "host.contoso.com".
                IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);
           
                // Create a TCP/IP socket.
                Socket sender = new Socket(AddressFamily.InterNetwork, 
                  SocketType.Stream, ProtocolType.Tcp );
           
                // Connect the socket to the remote endpoint. Catch any errors.
                try {
                  sender.Connect(remoteEP);
           
                  Console.WriteLine("Socket connected to {0}",
                    sender.RemoteEndPoint.ToString());
           
                  // Encode the data string into a byte array.
                  byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
           
                  // Send the data through the socket.
                  int bytesSent = sender.Send(msg);
           
                  // Receive the response from the remote device.
                  int bytesRec = sender.Receive(bytes);
                  Console.WriteLine("Echoed test = {0}",
                    Encoding.ASCII.GetString(bytes,0,bytesRec));
           
                  // Release the socket.
                  sender.Shutdown(SocketShutdown.Both);
                  sender.Close();
                  
                } catch (ArgumentNullException ane) {
                  Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
                } catch (SocketException se) {
                  Console.WriteLine("SocketException : {0}",se.ToString());
                } catch (Exception e) {
                  Console.WriteLine("Unexpected exception : {0}", e.ToString());
                }
           
              } catch (Exception e) {
                Console.WriteLine( e.ToString());
              }
           }
           
            public static int Main(String[] args) {
              StartClient();
              return 0;
           }
          }
          posted on 2007-06-08 13:49 注銷..... 閱讀(2540) 評(píng)論(1)  編輯  收藏 所屬分類: .net摘要

          評(píng)論

          # c# vs2005 好象不存在 StateObject這個(gè)類[未登錄](méi) 2008-05-08 21:01 xy
          vs2005 好象不存在 StateObject這個(gè)類
          在上面的異步套接字程序中有這2句 :
          StateObject state=new StateObject();
          State.workSocket=handler;
          假如不存在,應(yīng)該用什么來(lái)代替這2行代碼,才能獲取狀態(tài)???請(qǐng)大蝦們指點(diǎn).  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 北川| 广元市| 武平县| 盐亭县| 汾阳市| 永济市| 宜昌市| 武宣县| 曲水县| 甘孜| 鄯善县| 综艺| 怀仁县| 温泉县| 黄大仙区| 承德县| 灵石县| 广平县| 东辽县| 玛纳斯县| 那曲县| 武城县| 赤峰市| 马关县| 桐乡市| 富源县| 莱西市| 乌苏市| 平阳县| 九寨沟县| 浦东新区| 昆明市| 嘉义县| 项城市| 永靖县| 双江| 门头沟区| 德州市| 海伦市| 砀山县| 衡水市|