• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
只是向上走
采菊东篱下,悠然见南山。
博客园    首页    新随笔    联系   管理    订阅  订阅
C#网络编程---(2) 经过验证并调试后适合自身环境的客户端socket通信

本文参考了http://www.codeproject.com/KB/IP/socketasynceventargssampl.aspx

作了一些修改

在.NET 2.0 SP1上可以使用SocketAsyncEventArgs类,本文的代码就是用Microsoft Visual Studio .NET 2005编写的。

Code
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace SocketAsyncClient
{
    
/**//// <summary>
    
/// socket客户端
    
/// 异步实现
    
/// </summary>

    public sealed class SocketClient : IDisposable
    
{
        
/**//// <summary>
        
/// Constants for socket operations.
        
/// </summary>

        private const Int32 ReceiveOperation = 1, SendOperation = 0;

        
/**//// <summary>
        
/// The socket used to send/receive messages.
        
/// </summary>

        private Socket clientSocket;

        
/**//// <summary>
        
/// Flag for connected socket.
        
/// </summary>

        private Boolean connected = false;
      
        
public Boolean Connected
        
{
            
get { return connected; }
        }



        
/**//// <summary>
        
/// Listener endpoint.
        
/// </summary>

        private IPEndPoint hostEndPoint;

        
/**//// <summary>
        
/// Signals a connection.
        
/// </summary>

        private AutoResetEvent autoConnectEvent = new AutoResetEvent(false);
       
// private static AutoResetEvent autoConnectEvent = new AutoResetEvent(false); 

        
/**//// <summary>
        
/// Signals the send/receive operation.
        
/// </summary>

       // private static AutoResetEvent[] autoSendReceiveEvents = new AutoResetEvent[]
             private  AutoResetEvent[] autoSendReceiveEvents = new AutoResetEvent[]
        
{
            
new AutoResetEvent(false),
            
new AutoResetEvent(false)
        }
;

        
/**//// <summary>
        
/// Create an uninitialized client instance.  
        
/// To start the send/receive processing
        
/// call the Connect method followed by SendReceive method.
        
/// </summary>
        
/// <param name="hostName">Name of the host where the listener is running.</param>
        
/// <param name="port">Number of the TCP port from the listener.</param>

        public SocketClient(String hostName, Int32 port)
        
{
            
// Get host related information.
            IPHostEntry host = Dns.GetHostEntry(hostName);

            
// Addres of the host.
            IPAddress[] addressList = host.AddressList;

            
// Instantiates the endpoint and socket.
            this.hostEndPoint = new IPEndPoint(addressList[addressList.Length - 1], port);
            
this.clientSocket = new Socket(this.hostEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

        }


        
/**//// <summary>
        
/// Connect to the host.
        
/// </summary>
        
/// <returns>True if connection has succeded, else false.</returns>

        public void Connect()
        
{
            
            SocketAsyncEventArgs connectArgs 
= new SocketAsyncEventArgs();

            connectArgs.UserToken 
= this.clientSocket;
            connectArgs.RemoteEndPoint 
= this.hostEndPoint;
            connectArgs.Completed 
+= new EventHandler<SocketAsyncEventArgs>(OnConnect);
            
            clientSocket.ConnectAsync(connectArgs);            
            autoConnectEvent.WaitOne();        
            

            SocketError errorCode 
= connectArgs.SocketError;
            
            
if (errorCode != SocketError.Success)
            
{
                
throw new SocketException((Int32)errorCode);
            }

           

        }


        
/**//// <summary>
        
/// Disconnect from the host.
        
/// </summary>

        public void Disconnect()
        
{
            clientSocket.Disconnect(
false);
        }


        
private void OnConnect(object sender, SocketAsyncEventArgs e)
        
{
            
// Signals the end of connection.
            autoConnectEvent.Set();

            
// Set the flag for socket connected.
            this.connected = (e.SocketError == SocketError.Success);
        }


        
private void OnReceive(object sender, SocketAsyncEventArgs e)
        
{ 
            
// Signals the end of receive.
            autoSendReceiveEvents[SendOperation].Set();         
        }


        
private void OnSend(object sender, SocketAsyncEventArgs e)
        
{
            
// Signals the end of send.
            autoSendReceiveEvents[ReceiveOperation].Set();
           

            
if (e.SocketError == SocketError.Success)
            
{
                
if (e.LastOperation == SocketAsyncOperation.Send)
                
{                   
                    
// Prepare receiving.
                    Socket s = e.UserToken as Socket;

                    
byte[] receiveBuffer = new byte[255];
                    e.SetBuffer(receiveBuffer, 
0, receiveBuffer.Length);
                    e.Completed 
+= new EventHandler<SocketAsyncEventArgs>(OnReceive);                  

                 
                    s.ReceiveAsync(e);


                    
//  Encoding.ASCII.GetString(s..Buffer, completeArgs.Offset, completeArgs.BytesTransferred);

                }

            }

            
else
            
{
                
this.ProcessError(e);
            }

        }


       

        
/**//// <summary>
        
/// Close socket in case of failure and throws a SockeException according to the SocketError.
        
/// </summary>
        
/// <param name="e">SocketAsyncEventArg associated with the failed operation.</param>

        private void ProcessError(SocketAsyncEventArgs e)
        
{
            Socket s 
= e.UserToken as Socket;
            
if (s.Connected)
            
{
                
// close the socket associated with the client
                try
                
{
                    s.Shutdown(SocketShutdown.Both);
                }

                
catch (Exception)
                
{
                    
// throws if client process has already closed
                }

                
finally
                
{
                    
if (s.Connected)
                    
{
                        s.Close();
                    }

                }

            }


            
// Throw the SocketException
            throw new SocketException((Int32)e.SocketError);
        }


        
/**//// <summary>
        
/// Exchange a message with the host.
        
/// </summary>
        
/// <param name="message">Message to send.</param>
        
/// <returns>Message sent by the host.</returns>

        public String SendReceive(String message)
        
{
            
//指示应挂起此线程以使其他等待线程能够执行
            System.Threading.Thread.Sleep(0);            
            
            
if (this.connected)
            
{
                
// Create a buffer to send.
                Byte[] sendBuffer = Encoding.Default.GetBytes(message);
                
//StrHelper.Str2AscArr(message);

                
// Prepare arguments for send/receive operation.
                SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();
                completeArgs.SetBuffer(sendBuffer, 
0, sendBuffer.Length);
                completeArgs.UserToken 
= this.clientSocket;
                completeArgs.RemoteEndPoint 
= this.hostEndPoint;
                completeArgs.Completed 
+= new EventHandler<SocketAsyncEventArgs>(OnSend);

                
// Start sending asyncronally.
                clientSocket.SendAsync(completeArgs);

                
// Wait for the send/receive completed.
                AutoResetEvent.WaitAll(autoSendReceiveEvents);
              
                StringBuilder resultMsg 
= new StringBuilder();
                resultMsg.Append(Encoding.Default.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred));

                
while ((completeArgs.UserToken as Socket).Available > 0)
                
{
                    clientSocket.ReceiveAsync(completeArgs);
                    AutoResetEvent.WaitAll(autoSendReceiveEvents);
                    resultMsg.Append(Encoding.Default.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred));
                }


                
return resultMsg.ToString();


                
// return Encoding.ASCII.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred);


            }

            
else
            
{
                
throw new SocketException((Int32)SocketError.NotConnected);
            }

        }


        
IDisposable Members#region IDisposable Members

        
/**//// <summary>
        
/// Disposes the instance of SocketClient.
        
/// </summary>

        public void Dispose()
        
{
            autoConnectEvent.Close();
            autoSendReceiveEvents[SendOperation].Close();
            autoSendReceiveEvents[ReceiveOperation].Close();
            
if (this.clientSocket.Connected)
            
{
                
this.clientSocket.Close();
            }

        }


        
#endregion

    }

}

 

 

 

posted on 2009-05-20 15:19  jes.shaw  阅读(490)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3