Linux socket发送消息,C#的Socket简单实现消息发送

Socket一般用于网络之间的通信,在这里,实现的是服务端与客户端的简单消息通信。

首先是客户端的搭建,一般步骤是先建立Socket绑定本地的IP和端口,并对远端连接进行连接进行监听,这里的监听一般开启后台线程进行循环处理;如果远端有连接到本机的Socket的端口,则获取一个新的Socket对象并重新添加一个线程用于对远端地址进行消息通信(消息的收发),这样,服务端的Socket就简单实现,下面是winForm的具体实现。

一、先建立Socket的服务类SocketServerManager,用于对Socket各种操作的统一管理:

public class SocketManager

{

Socket _socket = null;

EndPoint _endPoint = null;

bool _isListening = false;

int BACKLOG = 10;

public SocketManager(string ip, int port)

{

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPAddress _ip = IPAddress.Parse(ip);

_endPoint = new IPEndPoint(_ip, port);

}

public void Start()

{

_socket.Bind(_endPoint); //绑定端口

_socket.Listen(BACKLOG); //开启监听

Thread acceptServer = new Thread(AcceptWork); //开启新线程处理监听

acceptServer.IsBackground = true;

_isListening = true;

acceptServer.Start();

}

public void AcceptWork()

{

while (_isListening)

{

Socket acceptSocket = _socket.Accept();

if (acceptSocket != null)

{

Thread socketConnectedThread = new Thread(newSocketReceive);

socketConnectedThread.IsBackground = true;

socketConnectedThread.Start(acceptSocket);

}

Thread.Sleep(200);

}

}

public void newSocketReceive(object obj)

{

Socket socket = obj as Socket;

while (true)

{

try

{

if (socket == null) return;

//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数

socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallBack, buffer);

}

catch (Exception ex)

{

return;

}

Thread.Sleep(100);

}

}

private void ReceiveCallBack(IAsyncResult ar)

{

}

}

public class SockeServertManager

上面是Socket管理类的模型,具体的方法是初始化和开启监听,接下来就是在Form的界面调用建立类和Start方法。

客户端同样是初始化socket,然后就不是监听socket,而是调用Connect连接指定的Socket地址,最后是开启新的线程接收和发送消息。

public class SocketClientManager

{

public Socket _socket = null;

public EndPoint endPoint = null;

public bool _isConnected = false;

public SocketClientManager(string ip, int port)

{

IPAddress _ip = IPAddress.Parse(ip);

endPoint = new IPEndPoint(_ip, port);

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

}

public void Start()

{

_socket.BeginConnect(endPoint, ConnectedCallback, _socket);

_isConnected = true;

Thread socketClient = new Thread(SocketClientReceive);

socketClient.IsBackground = true;

socketClient.Start();

}

public void SocketClientReceive()

{

while (_isConnected)

{

try {

_socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallback, buffer);

}

catch (SocketException ex)

{

_isConnected = false;

}

Thread.Sleep(100);

}

}

public void ReceiveCallback(IAsyncResult ar)

{

}

}

public class SocketClientManager

主要记住的是,客户端是监听Socket是固定的,是监听绑定地址的,每当有新的连接访问,则开启新的线程与之进行交互,而客户端只简单实现与服务端交互,服务端则只有一个。

Socket的进行发送与接收,一般是通过异步方法BeginReceive和BeginSend进行处理,方法一般带有回调函数,用于执行操作之后的处理。

还有就是连接的关闭,每关闭一个连接,先要结束在Socket所在的线程方法,我这里的处理是停止掉死循环的函数调用,每当线程所在函数执行完毕,则线程自动销毁。之后就是关闭所连接的socket。

下面是我程序的完整实现,为了方便socket的管理,我把服务器的所有与客户端对话的Socket统一用字典管理,并封装在SocketInfo的内部类中,消息的发送与接收必须先找到该连接socket。

最后就是界面的调用,完成Socket的网络消息交互。

下面是具体的实现及源码:

public class SocketManager

{

public Dictionary _listSocketInfo = null;

Socket _socket = null;

public SocketInfo socketInfo = null;

EndPoint _endPoint = null;

bool _isListening = false;

int BACKLOG = 10;

public delegate void OnConnectedHandler(string clientIP);

public event OnConnectedHandler OnConnected;

public delegate void OnReceiveMsgHandler(string ip);

public event OnReceiveMsgHandler OnReceiveMsg;

public event OnReceiveMsgHandler OnDisConnected;

public SocketManager(string ip, int port)

{

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

IPAddress _ip = IPAddress.Parse(ip);

_endPoint = new IPEndPoint(_ip, port);

_listSocketInfo = new Dictionary();

}

public void Start()

{

_socket.Bind(_endPoint); //绑定端口

_socket.Listen(BACKLOG); //开启监听

Thread acceptServer = new Thread(AcceptWork); //开启新线程处理监听

acceptServer.IsBackground = true;

_isListening = true;

acceptServer.Start();

}

public void AcceptWork()

{

while (_isListening)

{

Socket acceptSocket = _socket.Accept();

if (acceptSocket != null && this.OnConnected != null)

{

SocketInfo sInfo = new SocketInfo();

sInfo.socket = acceptSocket;

_listSocketInfo.Add(acceptSocket.RemoteEndPoint.ToString(), sInfo);

OnConnected(acceptSocket.RemoteEndPoint.ToString());

Thread socketConnectedThread = new Thread(newSocketReceive);

socketConnectedThread.IsBackground = true;

socketConnectedThread.Start(acceptSocket);

}

Thread.Sleep(200);

}

}

public void newSocketReceive(object obj)

{

Socket socket = obj as Socket;

SocketInfo sInfo = _listSocketInfo[socket.RemoteEndPoint.ToString()];

sInfo.isConnected = true;

while (sInfo.isConnected)

{

try

{

if (sInfo.socket == null) return;

//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数

sInfo.socket.BeginReceive(sInfo.buffer, 0, sInfo.buffer.Length, SocketFlags.None, ReceiveCallBack, sInfo.socket.RemoteEndPoint);

}

catch (Exception ex)

{

return;

}

Thread.Sleep(100);

}

}

private void ReceiveCallBack(IAsyncResult ar)

{

EndPoint ep = ar.AsyncState as IPEndPoint;

SocketInfo info = _listSocketInfo[ep.ToString()];

int readCount = 0;

try

{

if (info.socket == null) return;

readCount = info.socket.EndReceive(ar);

}catch(Exception ex){

return;

}

if (readCount > 0)

{

//byte[] buffer = new byte[readCount];

//Buffer.BlockCopy(info.buffer, 0, buffer, 0, readCount);

if (readCount < info.buffer.Length)

{

byte[] newBuffer = new byte[readCount];

Buffer.BlockCopy(info.buffer, 0, newBuffer, 0, readCount);

info.msgBuffer = newBuffer;

}

else

{

info.msgBuffer = info.buffer;

}

string msgTip = Encoding.ASCII.GetString(info.msgBuffer);

if (msgTip == "\0\0\0faild")

{

info.isConnected = false;

if (this.OnDisConnected != null) OnDisConnected(info.socket.RemoteEndPoint.ToString());

_listSocketInfo.Remove(info.socket.RemoteEndPoint.ToString());

info.socket.Close();

return;

}

if (OnReceiveMsg != null) OnReceiveMsg(info.socket.RemoteEndPoint.ToString());

}

}

public void SendMsg(string text, string endPoint)

{

if (_listSocketInfo.Keys.Contains(endPoint) && _listSocketInfo[endPoint] != null)

{

_listSocketInfo[endPoint].socket.Send(Encoding.ASCII.GetBytes(text));

}

}

public void Stop()

{

_isListening = false;

foreach (SocketInfo s in _listSocketInfo.Values)

{

s.socket.Close();

}

}

public class SocketInfo

{

public Socket socket = null;

public byte[] buffer = null;

public byte[] msgBuffer = null;

public bool isConnected = false;

public SocketInfo()

{

buffer = new byte[1024 * 4];

}

}

}

public class SocketServerManager

public class SocketClientManager

{

public Socket _socket = null;

public EndPoint endPoint = null;

public SocketInfo socketInfo = null;

public bool _isConnected = false;

public delegate void OnConnectedHandler();

public event OnConnectedHandler OnConnected;

public event OnConnectedHandler OnFaildConnect;

public delegate void OnReceiveMsgHandler();

public event OnReceiveMsgHandler OnReceiveMsg;

public SocketClientManager(string ip, int port)

{

IPAddress _ip = IPAddress.Parse(ip);

endPoint = new IPEndPoint(_ip, port);

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

}

public void Start()

{

_socket.BeginConnect(endPoint, ConnectedCallback, _socket);

_isConnected = true;

Thread socketClient = new Thread(SocketClientReceive);

socketClient.IsBackground = true;

socketClient.Start();

}

public void SocketClientReceive()

{

while (_isConnected)

{

SocketInfo info = new SocketInfo();

try {

_socket.BeginReceive(info.buffer, 0, info.buffer.Length, SocketFlags.None, ReceiveCallback, info);

}

catch (SocketException ex)

{

_isConnected = false;

}

Thread.Sleep(100);

}

}

public void ReceiveCallback(IAsyncResult ar)

{

socketInfo = ar.AsyncState as SocketInfo;

if (this.OnReceiveMsg != null) OnReceiveMsg();

}

public void ConnectedCallback(IAsyncResult ar)

{

Socket socket = ar.AsyncState as Socket;

if (socket.Connected)

{

if (this.OnConnected != null) OnConnected();

}

else

{

if (this.OnFaildConnect != null) OnFaildConnect();

}

}

public void SendMsg(string msg)

{

byte[] buffer = Encoding.ASCII.GetBytes(msg);

_socket.Send(buffer);

}

public class SocketInfo

{

public Socket socket = null;

public byte[] buffer = null;

public SocketInfo()

{

buffer = new byte[1024 * 4];

}

}

}

public class SocketClientManager

ed33615e87c6d8744eb6e85e6cc05762.png

具体源码(.net4.5,vs2013)下载:

------------------------------------------分割线------------------------------------------

具体下载目录在 /2015年资料/1月/29日/C#的Socket简单实现消息发送/

------------------------------------------分割线------------------------------------------

0b1331709591d260c1c78e86d0c51c18.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值