发布时间:2023-12-03 10:00
其实网上已经有很多关于socket编程了,基本上大学还是学习,第一个通信的例子应该就是基于Socket通信的知识。
大学天天背TCP/IP 七层,四层协议的,我现在也不一定一口全部说出来。
啥事儿,不说,上来就干,咱先来个客户端,再来个服务端。
最后,看下效果,就OK。其他详细细节,可以MSDN查看。
新创建一个控制台项目,大致如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AeXYsM0N-1655300858514)(https://tupian.wanmeisys.com/markdown/1655291821441-69a9451c-b717-413d-bf6f-2e6670f8fe5d.png)]
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)
{ }
}
}
///
/// 接收客户端发来的信息,客户端套接字对象
///
///
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的服务端就已经创建,并启动了。
然后等客户端的连接,来,我么接下来搞客户端。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aO6dyAm4-1655300858516)(https://tupian.wanmeisys.com/markdown/1655298738548-fb8f6c79-c8a5-423d-91f6-21d63784d5ba.png)]
///
/// 客户端
///
///
///
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;
}
///
/// 消息的接收
///
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}\");
}
}
}
///
/// 发送数据
///
///
///
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();
}
对粘包粘包等都没有处理,算是简单的Demo样例,用起来处理简单的问题还是很方便的。
很多时候,想直接搞个服务,又不想用网上的,找又找半天。
索性,就自己写了个,方便自己用。
平时也出力不少。_
也可以关注 蓝创精英团队 微信公众号进行赏阅。
https://github.com/kesshei/NetServerDemo.git
https://gitee.com/kesshei/NetServerDemo.git
Java Web 利用 session 实现简单的购物车(数量可以累加)
webpack使用postcss,为css自动增加浏览器前缀
理解NLP迁移学习/Transformers/GPT/Bert中遇到的难点和笔记
android高德地图上加自定义菜单,自定义UI控件-UI界面定制-开发指南-Android 导航SDK | 高德地图API...
使用BERT + Bi-LSTM + CRF 实现命名实体识别
SpringBoot接口 - 如何优雅的对接口返回内容统一封装?
H5画布 canvas(一)canvas简介、绘制圆形/矩形、案例饼状图绘制
基于java springboot uniapp图书借阅系统源码(毕设)