其实网上已经有很多关于socket编程了,基本上大学还是学习,第一个通信的例子应该就是基于Socket通信的知识。
大学天天背TCP/IP 七层,四层协议的,我现在也不一定一口全部说出来。
啥事儿,不说,上来就干,咱先来个客户端,再来个服务端。.
最后,看下效果,就OK。其他详细细节,可以MSDN查看。
服务端Socket实现
新创建一个控制台项目,大致如下

创建服务
public NetServer(int port)
{
this.port = port;
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LocalAddress = GetLocalAddress().ToString();
ServerSocket.Bind(new IPEndPoint(GetLocalAddress(), port));
}
启动服务
public void Start()
{
ServerSocket.Listen(50);
//负责监听客户端的线程:创建一个监听线程
Thread threadwatch = new Thread(watchconnecting);
//将窗体线程设置为与后台同步,随着主线程结束而结束
threadwatch.IsBackground = true;
//启动线程
threadwatch.Start();
Console.WriteLine(LocalAddress + " : " + port);
Console.WriteLine("开启监听。。。");
Console.WriteLine("请勿输入任何数据,会停止服务!!!");
}
监听客户端发过来的请求
//监听客户端发来的请求
public void watchconnecting()
{
Socket connection = null;
//持续不断监听客户端发来的请求
while (true)
{
try
{
connection = ServerSocket.Accept();
}
catch (Exception ex)
{
//提示套接字监听异常
Console.WriteLine(ex.Message);
break;
}
try
{
//获取客户端的IP和端口号
IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
//客户端网络结点号
string remoteEndPoint = connection.RemoteEndPoint.ToString();
//显示与客户端连接情况
Console.WriteLine("成功与" + remoteEndPoint + "客户端建立连接!");
//IPEndPoint netpoint = new IPEndPoint(clientIP,clientPort);
IPEndPoint netpoint = connection.RemoteEndPoint as IPEndPoint;
//创建一个通信线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(recv);
Thread thread = new Thread(pts);
//设置为后台线程,随着主线程退出而退出
thread.IsBackground = true;
//启动线程
thread.Start(connection);
}
catch (Exception)
{ }
}
}
接收客户端的信息,并原文返回,
/// <summary>
/// 接收客户端发来的信息,客户端套接字对象
/// </summary>
/// <param name="socketclientpara"></param>
public void recv(object socketclientpara)
{
Socket socketServer = socketclientpara as Socket;
try
{
while (true)
{
//创建一个内存缓冲区,其大小为1024*1024字节 即1M
byte[] arrServerRecMsg = new byte[1024 * 1024];
//将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
try
{
int length = socketServer.Receive(arrServerRecMsg);
//Console.WriteLine(length);
//接受多少,发送多少
if (length > 0)
{
byte[] b = new byte[length];
Array.Copy(arrServerRecMsg, b, b.Length);
var ret = socketServer.Send(b);
//将发送的字符串信息附加到文本框txtMsg上
Console.WriteLine("客户端:" + socketServer.RemoteEndPoint + "发送客户端状态:" + ret + "返回结果:" + Encoding.UTF8.GetString(b) + ",time:" + DateTime.Now.ToString());
}
else
{
break;
}
}
catch (Exception ex)
{
//提示套接字监听异常
Console.WriteLine("客户端" + socketServer.RemoteEndPoint + "已经中断连接" + "\r\n" + ex.Message + "\r\n" + ex.StackTrace + "\r\n");
//关闭之前accept出来的和客户端进行通信的套接字
socketServer.Close();
break;
}
}
//提示套接字监听异常
Console.WriteLine("客户端" + socketServer.RemoteEndPoint + "已经中断连接");
//关闭之前accept出来的和客户端进行通信的套接字
socketServer.Close();
}
catch (Exception)
{
}
}
如何获取到一个本地地址
public IPAddress GetLocalAddress()
{
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
int len = interfaces.Length;
for (int i = 0; i < len; i++)
{
NetworkInterface ni = interfaces[i];
if (ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
{
if (ni.Name == "本地连接")
{
IPInterfaceProperties property = ni.GetIPProperties();
foreach (UnicastIPAddressInformation ip in
property.UnicastAddresses)
{
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip.Address;
}
}
}
}
}
return IPAddress.Loopback; ;
}
启动服务实例
static void Main(string[] args)
{
Console.Title = "蓝创精英团队 NetServer 服务端";
Console.WriteLine("请输入本地需要监听的端口号:");
var read = Console.ReadLine();
NetServer server = new NetServer(read);
server.Start();
Console.WriteLine("服务启动,测试中!!");
Console.ReadLine();
}
这个时候socket的服务端就已经创建,并启动了。
然后等客户端的连接,来,我么接下来搞客户端。
创建客户端

连接服务端
/// <summary>
/// 客户端
/// </summary>
/// <param name="ip"></param>
/// <param name="Port"></param>
public netClient(string ip, int Port)
{
_ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.ipAddress = ip;
this.Port = Port;
}
启动连接服务端
public void Start()
{
_ClientSocket.Connect(new IPEndPoint(IPAddress.Parse(this.ipAddress), this.Port));//通过IP和端口号来定位一个所要连接的服务器端
//客户端网络结点号
remoteEndPoint = _ClientSocket.RemoteEndPoint.ToString();
LocalEndPoint = _ClientSocket.LocalEndPoint.ToString();
Console.WriteLine($"远端地址:{remoteEndPoint} 本端地址:{LocalEndPoint}");
threadReceive = new Thread(Receive);
threadReceive.IsBackground = true;
threadReceive.Start();
IsRun = true;
}
接收服务端发送过来的消息
/// <summary>
/// 消息的接收
/// </summary>
private void Receive()
{
byte[] TempData = new byte[1024 * 10];
while (IsRun)
{
//传递一个byte数组,用于接收数据。length表示接收了多少字节的数据
int length = _ClientSocket.Receive(TempData);
if (length == 0)
{
IsRun = false;
Console.WriteLine("服务器断开链接");
break;
}
else
{
string message = Encoding.UTF8.GetString(TempData, 0, length);//只将接收到的数据进行转化
Console.WriteLine($"远端地址:{remoteEndPoint} 本端地址:{LocalEndPoint} 获取到的数据:{message}");
}
}
}
发送消息到服务端
/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public int Send(string data)
{
return _ClientSocket.Send(Encoding.UTF8.GetBytes(data));
}
启动客户端实例
static void Main(string[] args)
{
Console.Title = "蓝创精英团队 NetServer 客户端";
netClient client = null;
bool isTrue = true;
while (isTrue)
{
Console.WriteLine("请输入本地需要连接的ip:端口号:");
var read = Console.ReadLine();
if (read.IndexOf(":") > -1)
{
var data = read.Split(':');
var ip = data[0];
var port = int.Parse(data[1]);
client = new netClient(ip, port);
client.Start();
break;
}
else
{
continue;
}
}
string message = string.Empty;
while ((message = Console.ReadLine()) != "exit")
{
client.Send(message);
}
Console.WriteLine("客户端启动,测试中!!");
Console.ReadLine();
}
实际案例
先启动服务端,输入端口号 9999
然后启动 客户端
输入127.0.0.1:9999 连接服务端
连接成功后,服务端会收到客户端建立的连接。
然后,客户端给服务端发送消息。
可以看到,效果还是很明显的。
需要注意的
对粘包粘包等都没有处理,算是简单的Demo样例,用起来处理简单的问题还是很方便的。
结束
很多时候,想直接搞个服务,又不想用网上的,找又找半天。
索性,就自己写了个,方便自己用。
平时也出力不少。^_^
代码地址
https://github.com/kesshei/NetServerDemo.git
https://gitee.com/kesshei/NetServerDemo.git