文章目录

  • 1.服务器端与一个客户端连接
    • 测试示图
    • 服务器
    • 客户端
  • 2.服务器与多客户端的连接
    • 异步实现服务器多连
    • 测试效果

1.服务器端与一个客户端连接

与一个客户端连接,客户端只能发送一条消息,下面是简单demo的图示。

测试示图

服务端和客户端在平台是不能同时运行的,调试的时候我是先把TCPClient发布成了exe,这里需要注意一下,不管是Rider还是VS都只能发布成exe,由于我是mac本想发布成app,但是尝试了方法很多都是不行,因为.net是针对Windows平台。
mac需要使用mono,服务器端我在Rider平台直接跑,exe则从终端打开,使用mono TCPCLient.exe
下图测试成功,客户端先收到“hello client!你好…” 之后输入 “你也好 服务器”发送给服务器,如图,服务器这边也成功收到了消息。

服务器端和客户端的ip可以写成本机127.0.0.1,或者本地IP,如果是局域网的话,ip并不是固定的可能会在某一周期内更新ip,需要随时间修改。此外,申请的端口号必须在1024~63365之间。

服务器

TCPServer

using System;
using System.Net.Sockets;
using System.Net;// use class Socket and TCP
namespace TCPServer
{internal class Program{public static void Main(string[] args){// 地址类型;socket类型:Dgram(UDP报文) TCP流Stream;协议Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 申请端口,绑定局域网ip 10.8.215.46(变动的)  127.0.0.1本机// IPAddress ipAddress= new IPAddress(new byte[]{10,8,215,46}); // 把ip构造成数组传递过去IPAddress ipAddress = IPAddress.Parse("xx.xx.xx.xx"); // Parse把一个ip字符串转换成对象传递// IpAdress xx.xx.xx.xx IpEedPoint IP地址+终端号IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 4869);// 绑定ip和端口号serverSocket.Bind(ipEndPoint);// 开始监听端口 设置50防止服务器崩溃 设置0表示不限制数量serverSocket.Listen(0); // 传递挂起的连接队列的最大长度 // 接收客户端信息 程序会暂停,直到有一个客户端连接过来才会继续向下运行Socket clientSocket = serverSocket.Accept(); // 接收一个客户端连接 返回一个Socket用来跟客户端进行通信// 向客户端发送一条数据string msg = "Hello client!你好...";byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); // 按照utf8将一个字符串转换成byte数组clientSocket.Send(data); // Send传递byte数组,需要将字符串转换成byte数组 需要使用支持中文的编码// 接收客户端一条消息 byte[] dataBuffer = new byte[1024]; // 接收时先定义一个数组int count =  clientSocket.Receive(dataBuffer); // 知道数组中前count个是接收到的数据string msgReceive = System.Text.Encoding.UTF8.GetString(dataBuffer, 0, count); // 转换成字符串Console.WriteLine(msgReceive);Console.ReadKey(); // 程序终止的太快,方便观察输出// 关闭服务器端clientSocket.Close(); // 关闭与客户端的连接serverSocket.Close(); // 关闭服务器自身的连接}}
}

客户端

TCPClient

using System;
using System.Net.Sockets;
using System.Net;namespace TCPClient
{internal class Program{ public static void Main(string[] args){Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 客户端不需要绑定ip和端口 只需要和服务器端建立连接clientSocket.Connect(new IPEndPoint(IPAddress.Parse("xx.xx.xx.xx"), 4869));// 服务器会向客户端发送消息,需要接收消息byte[] data = new byte[1024]; // 接收时先定义一个数组int count = clientSocket.Receive(data); // 知道数组中前count个是接收到的数据// 调用玩Receive后整个程序会暂停在这里,直到当它接收到服务器信息的时候string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); // 转换成字符串Console.WriteLine(msg);string str = Console.ReadLine(); // 读取用户一行输入传送给服务器端clientSocket.Send(System.Text.Encoding.UTF8.GetBytes(str));Console.ReadKey(); // 程序终止的太快,方便观察输出clientSocket.Close();}}
}

2.服务器与多客户端的连接

目前客户端只能发送一条数据,让客户端数据while(true)循环实现多条发送,当客户端输入c,使它正常关闭。

// 数据循环发送
while (true)
{string str = Console.ReadLine(); // 读取用户一行输入传送给服务器端// 输入c关闭if (str =="c"){clientSocket.Close();return;}clientSocket.Send(System.Text.Encoding.UTF8.GetBytes(str));
}

异步实现服务器多连

使用异步的方式双层递归使服务器能够与多个客户端连接。try catch对客户端非正常关闭进行监控。根据接收到的客户端信息长度为0时关闭对客户端的连接。

if (count == 0){clientSocket.Close();return;}

TCPServer

using System;
using System.Net.Sockets;
using System.Net;
using System.Text;// use class Socket and TCP
namespace TCPServer
{internal class Program{public static void Main(string[] args){StartServerAsync();// 暂停 防止中断Console.ReadKey();}// 异步 必须是静态 static void StartServerAsync(){// 地址类型;socket类型:Dgram(UDP报文) TCP流Stream;协议Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 申请端口,绑定局域网ip 10.8.215.46(变动的)  127.0.0.1本机// IPAddress ipAddress= new IPAddress(new byte[]{10,8,215,46}); // 把ip构造成数组传递过去IPAddress ipAddress = IPAddress.Parse("10.8.215.46"); // Parse把一个ip字符串转换成对象传递// IpAdress xx.xx.xx.xx IpEedPoint IP地址+终端号IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 4869);// 绑定ip和端口号serverSocket.Bind(ipEndPoint);// 开始监听端口 设置50防止服务器崩溃 设置0表示不限制数量serverSocket.Listen(0); // 传递挂起的连接队列的最大长度 // 接收客户端信息 程序会暂停,直到有一个客户端连接过来才会继续向下运行// Socket clientSocket = serverSocket.Accept(); // 接收一个客户端连接 返回一个Socket用来跟客户端进行通信serverSocket.BeginAccept(AcceptCallBack,serverSocket);}// 回调函数 接收到一个客户端连接的时候,要对客户端发起监听static void AcceptCallBack(IAsyncResult ar){Socket serverSocket = ar.AsyncState as Socket;Socket clientSocket = serverSocket.EndAccept(ar);// 向客户端发送一条数据string msg = "Hello client!你好...";byte[] data = System.Text.Encoding.UTF8.GetBytes(msg); // 按照utf8将一个字符串转换成byte数组clientSocket.Send(data); // Send传递byte数组,需要将字符串转换成byte数组 需要使用支持中文的编码// 持续不断的接收消息 BeginReceive()开始异步接收数据  偏移从0开始存,1024最大数量,事件方法,clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);// 接收完一个客户端之后,重新调用 继续处理下一个客户端连接serverSocket.BeginAccept(AcceptCallBack,serverSocket);}// 需要一个byte数组存储数据,静态方便内部访问static byte[] dataBuffer = new byte[1024];// 当服务器端接收到一条消息的时候,就会调用事件方法 如果想再去处理,传递数据的时候可以通过null进行传递static void ReceiveCallBack(IAsyncResult ar){// 使用try catch处理客户端异常关闭终端// 调用完BeginReceive,表示开始监听客户端数据的传递,当它就收到一条客户端数据的时候才会去调用// 把clientSocket当成一个参数传递到回调方法里面,通过ar.AsyncState来获取到SocketSocket clientSocket = null;try{clientSocket = ar.AsyncState as Socket;int count = clientSocket.EndReceive(ar); // 完成数据的接收  count代表接收了多少个字节的数据// 如果没有接收到数据就关闭 if (count == 0){clientSocket.Close();return;}// utf-8进行反编码string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);Console.WriteLine("从客户端接收到数据:" + msg);// 完成回调 一直接收数据clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);}catch (Exception e){Console.WriteLine(e);// 只出异常时关闭连接if (clientSocket != null){clientSocket.Close();}}}}
}

TCPClient

using System;
using System.Net.Sockets;
using System.Net;namespace TCPClient
{internal class Program{ public static void Main(string[] args){Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 客户端不需要绑定ip和端口 只需要和服务器端建立连接clientSocket.Connect(new IPEndPoint(IPAddress.Parse("10.8.215.46"), 4869));// 服务器会向客户端发送消息,需要接收消息byte[] data = new byte[1024]; // 接收时先定义一个数组int count = clientSocket.Receive(data); // 知道数组中前count个是接收到的数据// 调用玩Receive后整个程序会暂停在这里,直到当它接收到服务器信息的时候string msg = System.Text.Encoding.UTF8.GetString(data, 0, count); // 转换成字符串Console.WriteLine(msg);// 数据循环发送while (true){string str = Console.ReadLine(); // 读取用户一行输入传送给服务器端// 输入c关闭if (str =="c"){clientSocket.Close();return;}clientSocket.Send(System.Text.Encoding.UTF8.GetBytes(str));}// Console.ReadKey(); // 程序终止的太快,方便观察输出// clientSocket.Close();}}
}

测试效果

如图所示,每一个客户端都收到了来自服务器的消息,说明三个客户端都能与服务器建立正常的连接。

多个客户端都可以连续发送多条消息往服务器,服务器可以正常接收。

关闭客户端k3之后,服务器可以正常接收k2与k1的消息。在这里客户端k3属于正常关闭。

下面对客户端k2进行异常终止,在这之后,服务器正常接收客户端k1发送的消息,说明服务器与多个客户端之间的互联是正常的。

TCP服务器端与多个客户端连接的C#代码实现相关推荐

  1. SVN远程服务器端配置以及本地客户端连接最简易教程

    SVN远程服务器端配置以及本地客户端连接最简易教程 服务器端 服务器端下载 创建svn根目录 创建一个空的版本库 配置版本库 客户端 附注: svnserve地址被占用的问题 服务器端 服务器端下载 ...

  2. unity网络实战开发(丛林战争)-前期知识准备(006-修改服务器端开启异步处理客户端连接请求)

    使用工具:VS2015 使用语言:c# 作者:Gemini_xujian 参考:siki老师-<丛林战争>视频教程 继上一篇文章内容,这节课讲解一下修改服务器开启一步处理客户端连接请求. ...

  3. 发现TCP的一种错误----客户端连接失败(10055错误号)

    在客户端连接7302TCP端口失败,关闭程序,启动sockettool也不行,出现错误号为 10055(发现队列满了或者空间不足).通过查网上资料,发现有两个方法:设置 ( TcpTimedWaitD ...

  4. TCP实现服务器与单客户端连接(多线程)

    局域网内实现单客户端与服务器通信 客户端通过配置ip和端口号来连接服务器 客户端和服务器端各自具有发送和接收线程,可以实现一方持续发送 服务器端 package Net;import java.io. ...

  5. qt5 tcp服务器编程 多固定客户_如何编程实现电脑与智能小车通信?

    51智能小车编程 最近在做智能小车,需要实现编写上位机控制智能小车行驶方向与运行速度.因此首先需要解决的问题就是需要考虑如何实现计算机与智能小车进行通信.所使用硬件设备主要包括51单片机开发板.ESP ...

  6. C#网络编程,多个客户端连接服务器端并发送消息

    最近学习进度到了C#网络编程,在学习这一章节的知识点,写了一些小demo. 此次发表的为服务器监听端口,和多个客户端连接,获取多个客户端发来的消息. 服务器端代码: using System.Net; ...

  7. Oracle新手笔记(2) 关于Oracle 9i或9i以上版本客户端连接Oracle 8i及8i版本以下服务器端中文字符乱码的解决办法...

    在做项目过程中,遇到Oracle 9i或9i版本以上客户端连接Oracle 8i及8i版本以下服务器端时,查询出来的中文数据全部变成了乱码.经查询资料终于解决了乱码问题. 开发工具是ASP.NET(C ...

  8. qt客户端连接服务器不响应,qt判断tcp客户端是否连接服务器

    qt判断tcp客户端是否连接服务器 内容精选 换一换 本章节指导您使用MongoDB客户端,通过弹性云服务器内网方式连接GaussDB(for Mongo)集群实例.操作系统使用场景:弹性云服务器的操 ...

  9. android tcp判断服务器是否断开,Android tcp客户端连接,然后从java服务器断开连接...

    我在我的电脑上执行java服务器并让我的android设备连接到它.我可以连接它,但一旦连接就会断开连接.我确信在android方面我需要做一些事情,但我很少迷失它.我有互联网许可,所以很好.Andr ...

  10. python tcp多个客户端连接服务器

    一.传输层** 该层为两台主机上的应用程序提供端到端的通信.传输层有两个传输协议:TCP(传输控制协议)和 UDP(用户数据报协议).其中,TCP是一个可靠的面向连接的协议,udp是不可靠的或者说无连 ...

最新文章

  1. C/C++包管理工具Conan简介
  2. Bleve:来自Couchbase、基于Go语言的全文索引与检索库
  3. mysql insert concat_MySQL常用内置函数说明+concat+insert(str,m,n,inser_str)+week(now())+ | 学步园...
  4. 中石油训练赛 - Spiral Matrix(找规律)
  5. mmap函数_Linux内存映射mmap原理分析
  6. asp.net Page.Controls对象(找到所有服务器控件)
  7. java多态编译_关于java:编译时多态是否是这样的运行时多态?
  8. Django入门4--admin
  9. Reactive Extensions 初识
  10. x86 android armv7,说说Android项目中的armeabi,armeabi-v7a和x86
  11. c语言实验报告参考文献,c语言编程参考文献
  12. 大前端 (六) -- HTML5 标签 5
  13. python期中考试试卷分析_最新期中考试试卷分析与反思
  14. 时间管理体会:1.不能中午大热天跑出去,消耗大、导致疲惫后,不易恢复 2. 小睡,比吃东西还管用
  15. 题目:哪些是Jsp的内置对象?
  16. SSM整合版本二之Ajax的CRUD
  17. Axure RP 9 for mac(交互原型设计软件)支持m1
  18. 2020 年数学建模华为杯试题
  19. TGP(WeGame)导致桌面消失的解决办法
  20. 大厂面试篇--2023软件测试八股文最全文档,有它直接大杀四方

热门文章

  1. ubuntu20更改登录背景图片
  2. 炸了炸了~翻译器中的王者,科大讯飞翻译器2.0横空出世!| 钛空智慧星球推荐...
  3. python 菜鸟教程 xml-【读书】Django教程(菜鸟教程)
  4. 材料成型计算机仿真技术,材料成型计算机模拟分析(各种仿真软件介绍).ppt
  5. 【数据集】计算机视觉,深度学习,数据挖掘数据集整理
  6. JS 判断数组的六种方法
  7. p6spy mysql8_druid数据源集成p6spy踩坑
  8. 新高考教师增值评价方式的再研究
  9. java生成zipf分布_数据存储中Zipf分布
  10. spyder pyecharts不显示_飞利浦292E2E评测丨宽屏显示器中的多面手