最近在园子里看了大神写的(面试官,不要再问我三次握手和四次挥手),忍不住写段程序来测试一番。

    在网上找了很多例子,大多只实现了TCP点对点通讯,但实际应用中,一个服务器端口往往要监听多个客户端发来的消息。

测试工具下载:https://download.csdn.net/download/nbyanghuichao/11872360

    本例采用System.Threading实现多线程监听,下面只介绍核心代码,省略了消息提示和错误处理,可以从我的GitHub获取完整代码:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/TCP.Client

数据声明:

private string _ip;//IP
private int _port;//端口
//客户端集合
public static List<TcpClientModel> clients = new List<TcpClientModel>
private static byte[] bytes = new byte[1024 * 100];
/// <summary>
/// 用于存储客户端
/// </summary>
public class TcpClientModel
{
/// <summary>
/// IP:Port
/// </summary>
public string RemoteEndPoint { get; set; }
/// <summary>
/// 客户端链接对象
/// </summary>
public TcpClient TcpClient { get; set; }
}

启动监听:

///启动监听
void Init()
{
try
{
IPAddress ip = IPAddress.Parse(_ip);
int port = _port;
TcpListener listener = new TcpListener(ip, port);
//启动监听
listener.Start();
tb_console.AppendText($"Listener...\r\n");
//异步接收 递归循环接收多个客户端
listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
}
catch (Exception ex)
{ }
}

接收客户端:

private void GetAcceptTcpclient(IAsyncResult State)
{
//处理多个客户端接入
    TcpListener listener = (TcpListener)State.AsyncState;
//接收到客户端请求
TcpClient client = listener.EndAcceptTcpClient(State);
//保存到客户端集合中
clients.Add(new TcpClientModel() { TcpClient = client, RemoteEndPoint = client.Client.RemoteEndPoint.ToString() });     //开启线程用来持续接收来自客户端的数据
Thread myThread = new Thread(() =>
{
ReceiveMsgFromClient(client);
});
myThread.Start();
listener.BeginAcceptTcpClient(new AsyncCallback(GetAcceptTcpclient), listener);
}

接收消息并响应客户端:

private void ReceiveMsgFromClient(object reciveClient)
{
TcpClient client = reciveClient as TcpClient;
if (client == null)
{
return;
}
while (true)
{
try
{
NetworkStream stream = client.GetStream();
int num = stream.Read(bytes, 0, bytes.Length); //将数据读到result中,并返回字符长度                  
            if (num != 0)
{
//把字节数组中流存储的数据以字符串方式赋值给str
//这里就是接收到的客户端消息
string str = Encoding.UTF8.GetString(bytes, 0, num);                //给客户端返回一个消息
                string msg = "Your message has been received by the server[" + str + "]"; bool result = TCPHelper.SendToClient(client, msg, out msg);
if (!result)
{
//发送失败
}
}
else
{  
//这里需要注意 当num=0时表明客户端已经断开连接,需要结束循环,不然会死循环一直卡住
break;
}
}
catch (Exception ex)
{
//链接失败 从集合中移除出错客户端
clients.Remove(clients.FirstOrDefault(m => m.RemoteEndPoint == client.Client.RemoteEndPoint.ToString()));
break;
} }
}

从服务器向客户端发送消息的工具类:

public static class TCPHelper
{
public static bool SendToClient(TcpClient client, string message,out string errorMsg)
{
try
{
byte[] bytes = new byte[1024 * 100];
bytes = Encoding.UTF8.GetBytes(message);
NetworkStream stream = client.GetStream();
stream.Write(bytes, 0, bytes.Length);
stream.Flush();
errorMsg = "";
return true;
}
catch (Exception ex)
{
errorMsg = ex.Message;
return false;
}
}
}

测试效果:

完整代码请关注:https://github.com/FB208/CodeSpace/tree/master/CodeSpace.CSharp/TCP.Client

.Net TCP探索(一)——TCP服务端开发(同时监听多个客户端请求)的更多相关文章

  1. TCP状态机:当服务端主动发FIN进TIME_WAIT,客户端源端口复用会发生什么

    0X01 正常情况下TCP连接会通过4次挥手进行拆链(也有通过RST拆除连接的可能,见为什么服务器突然回复RST--小心网络中的安全设备),下图TCP状态机展示了TCP连接的状态变化过程: 我们重点看 ...

  2. 自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求

    DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件. 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限. 所以 ...

  3. python网络编程TCP服务多客户端的服务端开发

    #服务多客户端TCP服务端开发 2 #方法说明 3 """ 4 bind(host,port)表示绑定端口号,host是ip地址,ip地址一般不进 行绑定,表示本机的任何 ...

  4. 网络编程之TCP客户端开发和TCP服务端开发

    开发 TCP 客户端程序开发步骤 创建客户端套接字对象 和服务端套接字建立连接 发送数据 接收数据 关闭客户端套接字 import socket if __name__ == '__main__': ...

  5. 异步tcp通信——APM.Core 服务端概述

    为什么使用异步 异步线程是由线程池负责管理,而多线程,我们可以自己控制,当然在多线程中我们也可以使用线程池.就拿网络扒虫而言,如果使用异步模式去实现,它使用线程池进行管理.异步操作执行时,会将操作丢给 ...

  6. TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q

    TCP协议下的服务端并发,GIL全局解释器锁,死锁,信号量,event事件,线程q 一.TCP协议下的服务端并发 ''' 将不同的功能尽量拆分成不同的函数,拆分出来的功能可以被多个地方使用 TCP服务 ...

  7. java 网络编程基础 TCP/IP协议:服务端ServerSocket;客户端Socket; 采用多线程方式处理网络请求

    1.Java中客户端和服务器端通信的简单实例 Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一 ...

  8. socket服务端开发之测试使用threading和gevent框架

    socket服务端开发之测试使用threading和gevent框架 话题是测试下多线程和gevent在socket服务端的小包表现能力,测试的方法不太严谨,也没有用event loop + pool ...

  9. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

随机推荐

  1. 从原理层面掌握@InitBinder的使用【享学Spring MVC】

    每篇一句 大魔王张怡宁:女儿,这堆金牌你拿去玩吧,但我的银牌不能给你玩.你要想玩银牌就去找你王浩叔叔吧,他那银牌多 前言 为了讲述好Spring MVC最为复杂的数据绑定这块,我前面可谓是做足了功课, ...

  2. SpringMVC的工作原理图

    SpringMVC的工作原理图: SpringMVC流程 1.  用户发送请求至前端控制器DispatcherServlet. 2.  DispatcherServlet收到请求调用HandlerMa ...

  3. spring boot发送其他邮件

    前面已经讲了使用springboot采用常规的javaweb方式发送邮件和使用spring模板发送邮件.但是发送的都是文本文件,现在来说一下使用spring模板发送一些其他的邮件. 1.pom.xml ...

  4. 前端自动化部署linux centOs + Jenkins + nignx + 单页面应用

    Jenkins是什么? Jenkins 是一款业界流行的开源持续集成工具,广泛用于项目开发,具有自动化构建.测试和部署等功能. 准备工作 Linux centOS系统阿里云服务器一个 码云一个存放vu ...

  5. 做一个logitic分类之鸢尾花数据集的分类

    做一个logitic分类之鸢尾花数据集的分类 Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例.数据集内包含 3 类共 150 条记录,每类各 50 个数据,每条记录都 ...

  6. jquery easyui dialog一进来直接最大化

    扩展自 $.fn.window.defaults.通过 $.fn.dialog.defaults 重写默认的 defaults. 对话框(dialog)是一个特殊类型的窗口,它在顶部有一个工具栏,在底 ...

  7. Hadoop&Hbase 双机热备--Pacemaker&DRBD部署

    相关文章   DRBD的介绍请参考http://blog.csdn.net/rzhzhz/article/details/7103772   DRBD的部署请参考http://blog.csdn.ne ...

  8. 关于样式style

    今天看到了一个bgcolor和以前看过的background-color,特意查了一下区别 百度是这么说的:background-color是标准CSS属性,bgcolor应该是IE扩展的html元素 ...

  9. 松软科技课堂:SQL-LEFT-JOIN 关键字

    SQL LEFT JOIN 关键字 LEFT JOIN 关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行. LEFT JOIN 关键 ...

  10. 教你用java统计目录下所有文档的词频

    本文是统计目录下所有文档的词频top10,非单个文档,包含中文和英文. 直接上代码: package com.huawei.wordcount; import java.io.BufferedRead ...