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

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

     public class SocketManager
{
Socket _socket = null;
EndPoint _endPoint = null;
bool _isListening = false;
int BACKLOG = ; 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();
}
} public void newSocketReceive(object obj)
{
Socket socket = obj as Socket;
while (true)
{
try
{
if (socket == null) return;
//这里向系统投递一个接收信息的请求,并为其指定ReceiveCallBack做为回调函数
socket.BeginReceive(buffer, , buffer.Length, SocketFlags.None, ReceiveCallBack, buffer);
}
catch (Exception ex)
{
return;
}
Thread.Sleep();
}
} 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, , buffer.Length, SocketFlags.None, ReceiveCallback, buffer);
}
catch (SocketException ex)
{
_isConnected = false;
} Thread.Sleep();
}
} public void ReceiveCallback(IAsyncResult ar)
{
}
}

public class SocketClientManager

主要记住的是,客户端是监听Socket是固定的,是监听绑定地址的,每当有新的连接访问,则开启新的线程与之进行交互,而客户端只简单实现与服务端交互,服务端则只有一个。
Socket的进行发送与接收,一般是通过异步方法BeginReceive和BeginSend进行处理,方法一般带有回调函数,用于执行操作之后的处理。
还有就是连接的关闭,每关闭一个连接,先要结束在Socket所在的线程方法,我这里的处理是停止掉死循环的函数调用,每当线程所在函数执行完毕,则线程自动销毁。之后就是关闭所连接的socket。

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

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

     public class SocketManager
{
public Dictionary<string,SocketInfo> _listSocketInfo = null;
Socket _socket = null;
public SocketInfo socketInfo = null;
EndPoint _endPoint = null;
bool _isListening = false;
int BACKLOG = ; 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<string, SocketInfo>();
} 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();
}
} 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, , sInfo.buffer.Length, SocketFlags.None, ReceiveCallBack, sInfo.socket.RemoteEndPoint);
}
catch (Exception ex)
{
return;
}
Thread.Sleep();
}
} private void ReceiveCallBack(IAsyncResult ar)
{
EndPoint ep = ar.AsyncState as IPEndPoint;
SocketInfo info = _listSocketInfo[ep.ToString()];
int readCount = ;
try
{
if (info.socket == null) return;
readCount = info.socket.EndReceive(ar);
}catch(Exception ex){
return;
}
if (readCount > )
{
//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, , newBuffer, , 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[ * ];
}
}
}

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, , info.buffer.Length, SocketFlags.None, ReceiveCallback, info);
}
catch (SocketException ex)
{
_isConnected = false;
} Thread.Sleep();
}
} 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[ * ];
}
}
}

public class SocketClientManager

具体源码(.net4.5,vs2013):具体源码 http://files.cnblogs.com/files/supheart/ServerBySocket.zip

C#的Socket简单实现消息发送的更多相关文章

  1. RabbitMQ 简单的消息发送与接收

    RabbitMQ是建立在AMQP(Advanced Message Queuing Protocol,高级消息队列协议)基础上的,而AMQP是建立在TCP协议之上的. 因此,RabbitMQ是需要建立 ...

  2. C# Socket异步实现消息发送--附带源码

    前言 看了一百遍,不如动手写一遍. Socket这块使用不是特别熟悉,之前实现是公司有对应源码改改能用. 但是不理解实现的过程和步骤,然后最近有时间自己写个demo实现看看,熟悉熟悉Socket. 网 ...

  3. java操作rabbitmq实现简单的消息发送(socket编程的升级)

    准备: 1.下载rabbitmq并搭建环境(和python那篇一样:http://www.cnblogs.com/g177w/p/8176797.html) 2.下载支持的jar包(http://re ...

  4. C#TCPClient应用-一个简单的消息发送和接收

    TcpSend窗口用于发送消息,另外写一个用于接收消息的应用程序,消息接受到以后,必须要关闭接收消息的窗口,才能在接收新的消息,不知道怎么能解决这个问题. 源代码: 发送消息的窗口代码 using S ...

  5. 深入探讨C#中Socket一次性搞定消息发送

    转载自:http://tech.chinaunix.net/a2010/0909/1101/000001101396.shtml     [IT168 技术文档]最近浏览了几篇有关Socket发送消息 ...

  6. Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

    本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...

  7. Python3学习之路~8.2 socket简单实例 实现ssh 发送大量数据

    实例1: 利用socket模拟客户端和服务器端各自收发一次数据: #Author:Zheng Na # 客户端 import socket # 声明socket类型,同时生成socket连接对象 cl ...

  8. activemq安装与简单消息发送接收实例

    安装环境:Activemq5.11.1, jdk1.7(activemq5.11.1版本需要jdk升级到1.7),虚拟机: 192.168.147.131 [root@localhost softwa ...

  9. 高效的TCP消息发送组件

    目前的.net 架构下缺乏高效的TCP消息发送组件,而这种组件是构建高性能分布式应用所必需的.为此我结合多年的底层开发经验开发了一个.net 下的高效TCP消息发送组件.这个组件在异步发送时可以达到每 ...

随机推荐

  1. org.apache.hadoop.conf-Configurable

    从包名可以看出这个包里面都是配置相关的类:从类名上可以看出这是一个接口,或者说配置类接口.内容很少. package org.apache.hadoop.conf; /** Something tha ...

  2. 11. Android框架和工具之 Logger(调试代码)

    1. Logger Logger是android是一个简单.漂亮.功能强大的Android日志程序. 日志程序提供了 : 线程信息Thread information 类信息Class informa ...

  3. 【阿里云产品公测】阿里云ACE部署通用完整教程及评测

    [阿里云产品公测]阿里云ACE部署通用完整教程及评测 作者:阿里云用户bailimei ACE应该是目前在公测的服务中应用最广泛的一项服务.在公测云引擎ACE前曾使用过新浪SAE,而ACE给我的最初印 ...

  4. Android读取RAM,ROM,SD卡容量

    1)简介 一般人们在买手机的时候,在手机配置上都会出现"内存容量:512MB ROM+512MB RAM "等等类似这样的说明,可能很多人都知道RAM的意思就是运存的意思,但是对于 ...

  5. extjs中grid对于其中表单的表头的读取以及是否隐藏的判断

    //获取grid的表头信息 var columns=baseGrid.columns;                     alert(columns.length); //判断列是否隐藏并输出表 ...

  6. 10个实用的但偏执的Java编程技术

    在沉浸于编码一段时间以后,你会渐渐对这些东西习以为常.因为,你知道的-- 任何事情有可能出错,没错,的确如此. 这就是为什么我们要采用"防御性编程",即一些偏执习惯的原因.下面是我 ...

  7. Oracle基础 TO_CHAR函数参考(转)

    Postgres 格式化函数提供一套有效的工具用于把各种数据类型(日期/时间,int,float,numeric)转换成格式化的字符串以及反过来从格式化的字符串转换成原始的数据类型. 注意:所有格式化 ...

  8. EasyGUI的安装

    1.下载EasyGUI 在官方网站上下载http://easygui.sourceforge.net/将安装包下载下来,放到桌面上并解压. 2.安装EasyGUI ①在开始菜单的搜索中输入cmd,打开 ...

  9. Kinect For Windows V2开发日志八:侦测、追踪人体骨架

    简介 Kinect一个很强大的功能就是它可以侦测到人体的骨骼信息并追踪,在Kinect V2的SDK 2.0中,它最多可以同时获取到6个人.每个人25个关节点的信息,并且通过深度摄像头,可以同时获取到 ...

  10. P1707 刷题比赛

    P1707 刷题比赛 10通过 38提交 题目提供者nodgd 标签倍增递推矩阵洛谷原创 难度提高+/省选- 提交该题 讨论 题解 记录 最新讨论 不科学 题目背景 nodgd是一个喜欢写程序的同学, ...