惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
S
Security Affairs
T
Tor Project blog
T
Threatpost
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
A
Arctic Wolf
K
Kaspersky official blog
O
OpenAI News
Spread Privacy
Spread Privacy
人人都是产品经理
人人都是产品经理
爱范儿
爱范儿
Simon Willison's Weblog
Simon Willison's Weblog
雷峰网
雷峰网
P
Privacy & Cybersecurity Law Blog
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
量子位
博客园_首页
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
IT之家
IT之家
N
News and Events Feed by Topic
博客园 - 司徒正美
V2EX - 技术
V2EX - 技术
S
Schneier on Security
博客园 - 叶小钗
Attack and Defense Labs
Attack and Defense Labs
AI
AI
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 【当耐特】
Jina AI
Jina AI
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
D
Darknet – Hacking Tools, Hacker News & Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
大猫的无限游戏
大猫的无限游戏
Cloudbric
Cloudbric
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
V
V2EX
S
SegmentFault 最新的问题
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
Microsoft Security Blog
Microsoft Security Blog

博客园 - 随风逝去(叶进)

MySQL分表(Partition)学习研究报告 用WPF+MongoDB开发房产信息收集器(4)——房产信息采集器总体介绍附程序下载 用WPF+MongoDB开发房产信息收集器(3)——MongoDB入门 用WPF+MongoDB开发房产信息收集器(2)——后台线程 用WPF+MongoDB开发房产信息收集器(1) 解决FireFox不能Debug Silverlight程序的问题 - 随风逝去(叶进) - 博客园 终于可以继续往下了! 回首2008 另类的二级域名实现方法 【更新 2008.10.16】触发C#Button的双击事件 触发C#Button的双击事件 到底要不要去面试? 【C#食谱】【面食】菜单7:用默认值初始化泛型变量 类和对象 【C#食谱】【杭帮菜】菜单2:写一个TCP客户端 C#Winform下用正则表达式限制TextBox只能输入数字 【C#食谱】【川菜】菜单1:列出被引用的程序集 实现需求工程的成功方法 实现需求工程的成功方法——难度:高;影响:低
【C#食谱】【杭帮菜】菜单1:写一个TCP服务端
随风逝去(叶进) · 2008-04-21 · via 博客园 - 随风逝去(叶进)

问题:

你需要写一个服务端去监听从某一个端口进来的一个TCP客户端的请求。然后,这些请求可以在服务端被处理,并且每一个响应都可以被发送到TCP客户端。我将在下一个“菜”中介绍怎么样创建一个TCP客户端和服务端进行交互。

解决方法:

我们创建一个MyTcpServer的类来监听从一个端口进来的基于TCP终端的请求:

class MyTcpServer
{
    Private Members

    构造函数 // 构造函数
}

这个MyTCPServer类有两个属性:

  • Address(IPAddress)
  • Port(int)

下面这些返回当前服务端正在监听的地址和端口,并且返回监听的状态:

属性

这个Listen方法告诉MyTcpServer类开始在某个地址和端口对上开始监听。你创建并启动了一个TcpListener,然后调用它的AcceptTcpClient方法去等待一个客户端请求的到来。一旦客户端连接成功,一个请求将被发送到线程池去处理客户端,它将运行ProcessClient方法。

监听器将在处理完客户端的请求后关闭:

public void Listen()
{
    try
    {
        lock (_syncRoot)
        {
            _listener 
= new TcpListener(_address, _port);
            // 启动服务器
            _listener.Start();

            // 设置为监听状态
            _listening = true;
        }


        // 监听
        do
        {
            Trace.Write(
"Looking for someone to talk to…?");

            // 等待连接
            TcpClient newClient = _listener.AcceptTcpClient();
              Trace.WriteLine(
"Connected to new client");

            // 排队处理客户的请求
            ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessClient), newClient);
        }
while (_listening);
    }

    catch (SocketException se)
    {
        Trace.WriteLine(
"SocketException: " + se.ToString()); 
    }
 
    finally 
    {
        // 关闭
        StopListening();
    }

}

StopListening方法使得TCPServer停止监听请求:

public void StopListening()
{
    if (_listening)
    {
        lock (_syncRoot)
      
{
            // 设置为非监听状态
            _listening = false;
            // 关闭
            _listener.Stop();
        }

    }

}


ProcessClient方法在一个线程池上被执行用来处理一个已经连接的客户端。它通过TcpClient.GetStream方法从客户端得到NetworkStream,然后读取整个请求。在返回一个响应后,它关闭客户端的连接。

私有方法

一个简单的监听客户端的服务端程序是这样的:

        class Program
        
{
            
static MyTcpServer server = null;

            
static void Main(string[] args)
            
{
                
// 在另一个线程上运行服务端
                ThreadPool.QueueUserWorkItem(RunServer);
                Console.WriteLine(
"Press Esc to stop the server…?");
                ConsoleKeyInfo cki;
                
while (true)
                
{
                    cki 
= Console.ReadKey();
                    
if (cki.Key == ConsoleKey.Escape)
                        
break;
                }

            }


            
static void RunServer(object stateInfo)
            
{
                
// 启动
                server = new MyTcpServer(IPAddress.Loopback, 55555);
                server.Listen();
            }

        }


具体的输出将在下一个配套的菜(写一个TCP客户端)中再发布出来。
讨论:
传输控制协议(TCP)是目前Internet上被广泛使用的协议。TCP协议是对从一个终端到另一个终端正确发生数据包负责的(有连接的)。
它使用Internet协议(IP)去传输数据。IP从端到端的获取数据包;TCP检查数据包是否被正确地发送了,有没有丢包,有没有乱序;如果有,TCP会使丢失的或损害的包重新发送。
TCPServer类是处理从基于TCP的客户端发送过来的请求的基本服务端机制。
MyTcpServer类使用传进来的IP地址和端口号作为参数,并且在Listen方法中在该IP地址和端口上创建一个TcpListener。
一旦创建成功,TcpListener.Start方法被调用来启动服务器。个阻塞的AcceptTcpClient方法被调用来监听来自基于TCP的客户端的请求。一旦建立连接,ProcessClient方法将执行。
在这个方法中,服务器从客户端读取数据,并返回一个可信的响应。服务器通过NetworkStream.Close方法和TcpClient.Close方法来中断和客户端的连接。
StopListening方法被调用的时候,服务器停止监听。StopListening方法通过调用TcpListener.Stop方法来使服务器掉线。

写一个TCP客户端