您的位置:首页 > 理论基础 > 计算机网络

Socket(Tcp)通信服务端

2014-08-28 17:32 113 查看
又是一段时间了,感觉最近挺乱的,今天有些时间,搞了下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");
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: