Socket(Tcp)通信服务端

又是一段时间了,感觉最近挺乱的,今天有些时间,搞了下socket的服务器。

 

先来看下服务端和客户端的流程如下:


 

我个人比较偏爱异步通信,今天主要以异步通信来讲一讲socket

 

1、Socket的构造函数来创建Socket:

Socket(AddressFamily,SocketType, ProtocolType)

AddressFamily:指定的地址族

SocketType:套接字类型

ProtocolType:协议类型

参考:_listener = newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

 

2、Bind()绑定端口和IP

public void Bind

(

         EndPoint localEP

)

参考:

IPAddress_ipAddress = IPAddress.Parse("192.168.1.216");

IPEndPoint_ipEndPoint = new IPEndPoint(_ipAddress , 2222);

_listener.Bind(_ipEndPoint);

 

3、listen()监听socket

public void Listen
(
           int backlog
)

参考:_listener.Listen(10)

 

4、accept()接收来自客户端的请求

public IAsyncResult BeginAccept
(
           AsyncCallback callback,
           Object state
)

参考:_listener.BeginAccept(newAsyncCallback(AcceptCallBack),_listener);

 

5、receive()从socket中读取字符

public IAsyncResult BeginReceive(
         byte[] buffer,// Byte 类型的数组,它是存储接收到的数据的位置。
         int offset,// buffer 参数中存储所接收数据的位置,该位置从零开始计数。
         int size,//要接收的字节数。
         SocketFlags socketFlags,// SocketFlags 值的按位组合。
         AsyncCallback callback,//一个 AsyncCallback 委托,它引用操作完成时要调用的方法。
         Object state//一个用户定义对象,其中包含接收操作的相关信息。 当操作完成时,此对象会被传递给 EndReceive 委托。
)

参考:_handlerEnd.BeginReceive(_state._buffer,0,StateObject._bufferSize,0,newAsyncCallback(ReceiveCallBack),_state);

 

6、close()关闭socket,并释放资源

public void Close()

参考:_handlerEnd.Close();

 

 注意: PC端汉字传输时,需要的格式如下

string Message  = "Lee";

byte[] bytes =Encoding.GetEncoding("GB2312").GetBytes(Message);


完整参考代码如下:

usingUnityEngine;
usingSystem.Collections;
usingSystem;
usingSystem.Net;
usingSystem.Net.Sockets;
usingSystem.Threading;
usingSystem.Text;
usingSystem.Collections.Generic;
 
///<summary>
///StateObject为BeginReceive时的一种状态,用来存储数据
///</summary>
publicclass StateObject
{
         public Socket _workSocket;
 
         public const int _bufferSize = 1024;
 
         public byte[] _buffer = new byte[_bufferSize];
 
         public StringBuilder _sb = newStringBuilder();
}
 
publicclass TcpSever 
{
         public static ManualResetEvent _allOne= new ManualResetEvent(false);
 
         public static TcpSever _inSingle;
 
         private Socket _listener;
         public List<Socket> _clientList =new List<Socket>();
 
         /// <summary>
         /// 单例模式的类
         /// </summary>
         /// <returns>Theinsigle.</returns>
         public static TcpSever GetInsigle()
         {
                   if(_inSingle == null)
                   {
                            _inSingle = newTcpSever();
                   }
                   return _inSingle;
                    
         }
 
         public TcpSever ()
         {
                   IPAddress _ipAddress =IPAddress.Parse("192.168.1.216");
                   IPEndPoint _ipEndPoint = newIPEndPoint(_ipAddress , 2222);
 
                   _listener = newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
 
                   _listener.Bind(_ipEndPoint);
 
                   /// <summary>
                   /// 新建_threadListenFunciton线程,用来监听客户端连接
                   /// </summary>
                   Thread _threadListenFunciton= new Thread(new ThreadStart(ListenFuncition));
                   _threadListenFunciton.IsBackground= true;
                   _threadListenFunciton.Start();
         }
         void ListenFuncition()
         {
                   try
                   {
                            _listener.Listen(10);
                           
                            while(true)
                            {
                                     _allOne.Reset();
                                     _listener.BeginAccept(newAsyncCallback(AcceptCallBack),_listener);
                                     _allOne.WaitOne();
                            }
                   }
                   catch
                   {}
         }
 
         /// <summary>
         ///异步Accept的回调函数
         /// </summary>
         /// <paramname="_ar">_ar.</param>
         void AcceptCallBack(IAsyncResult _ar)
         {
                   _allOne.Set();
 
                   Socket _listenerSelf =(Socket)_ar.AsyncState;
                   Socket _handlerEnd =_listenerSelf.EndAccept(_ar);
 
        
                   /// <summary>
                   ///用于向客户端发送消息的Socket,全部放入泛型列表中
                   /// </summary>
                   _clientList.Add(_handlerEnd);
 
                   StateObject _state = newStateObject ();
                   _state._workSocket =_handlerEnd;
 
                   _handlerEnd.BeginReceive(_state._buffer,0,StateObject._bufferSize,0,newAsyncCallback(ReceiveCallBack),_state);
 
         }
 
         /// <summary>
         /// 异步Receive的回调函数
         /// </summary>
         /// <paramname="_ar">_ar.</param>
         void ReceiveCallBack(IAsyncResult _ar)
         {
                   StateObject _state =(StateObject )_ar.AsyncState;
 
                   Socket _handlerEnd =_state._workSocket;
 
                   int _receiveLength =_handlerEnd.EndReceive(_ar);
 
                   if(_receiveLength >0 )
                   {
 
                            string _receiveData= Encoding.ASCII.GetString(_state._buffer,0,_receiveLength);
                            ReceiveData(_receiveData);
 
                            ///<summary>
                            ///字符串拼接
                            ///</summary>
                            _state._sb.Append(Encoding.ASCII.GetString(_state._buffer,0,_receiveLength));
                            string _ReceiveData= _state._sb.ToString();
                            ReceiveData(_ReceiveData);
 
                            _handlerEnd.BeginReceive(_state._buffer,0,StateObject._bufferSize,0,newAsyncCallback(ReceiveCallBack),_state);
                   }
         }
 
         /// <summary>
         ///向客户端发送消息
         /// </summary>
         void SendMessage( Socket_handlerEnd,string _value)
         {
                   byte[] _sendData =Encoding.ASCII.GetBytes(_value);
 
                   _handlerEnd.BeginSend(_sendData,0,_sendData.Length,0,newAsyncCallback(SendCallBack),_handlerEnd);
         }
 
         /// <summary>
         /// 异步Send的回调函数
         /// </summary>
         void SendCallBack(IAsyncResult _ar)
         {
                   Socket _handlerEnd =(Socket)_ar.AsyncState;
 
                   int _sendLength =  _handlerEnd.EndSend(_ar);
 
                   ///<summary>
                   ///当通讯结束时,Shutdown()禁止该套接字上的发送和接收,Close()关闭套接字并释放资源
                   ///</summary>
                   //_handlerEnd.Shutdown(SocketShutdown.Both);
                   //_handlerEnd.Close();
                   Debug.Log("发送"+_sendLength+"个字节");
         }
 
         public string  ReceiveData(string _data)
         {
                   Debug.Log(_data);
                   return _data;
         }
         public void SendData(string _data)
         {
                   Debug.Log(_data);
                   //向每个客户端发送数据
                   foreach(Socket _client in_clientList)
                   {
                            SendMessage(_client,_data);
 
                            //客户端IP和Port信息
                            EndPointtempRemoteEP = _client.RemoteEndPoint;
                            IPEndPointtempRemoteIP = ( IPEndPoint )tempRemoteEP ;
                           
                            stringrempip=tempRemoteIP.Address.ToString();
                            stringremoport=tempRemoteIP.Port.ToString();
                            Debug.Log(rempip+":"+remoport);
                   }
 
 
 
         }
}


 

调用代码如下:

usingUnityEngine;
usingSystem.Collections;
 
publicclass TcpServeTest : MonoBehaviour {
 
         // Use this for initialization
         void Start ()
         {
                   TcpSever.GetInsigle();
 
         }
        
         // Update is called once per frame
         void Update ()
         {
                   if(Input.GetMouseButtonDown(0))
                   {
                            TcpSever.GetInsigle().SendData("ddd");
                   }
        
         }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值