[转贴]基于UDP、TCP协议的C#网络编程之二

简介: 转自新浪"烈·翼·焚·天"的博客,原文地址:http://blog.sina.com.cn/s/blog_4c459776010009c3.html~type=v5_one&label=rela_nextarticle 第二截,讲讲基于TCP协议的网络编程,与UDP不同的是,基于TCP协议的编程的服务器端有一个监听对象:TcpListener,它负责监听来自客户端的消息并处理,并且必须在保持连接的情况下与客户端保持互动,下面举个例子,TCP不怎么复杂,只是综合要求较高,如果想编出个象样的东西,对多线程,事件委托等等都需要有较高的认识,当然,还要对协议本身有深刻的理解。

转自新浪"烈·翼·焚·天"的博客,原文地址:http://blog.sina.com.cn/s/blog_4c459776010009c3.html~type=v5_one&label=rela_nextarticle

第二截,讲讲基于TCP协议的网络编程,与UDP不同的是,基于TCP协议的编程的服务器端有一个监听对象:TcpListener,它负责监听来自客户端的消息并处理,并且必须在保持连接的情况下与客户端保持互动,下面举个例子,TCP不怎么复杂,只是综合要求较高,如果想编出个象样的东西,对多线程,事件委托等等都需要有较高的认识,当然,还要对协议本身有深刻的理解。咱水平不到,来个课堂实例。

     示例一:基于TCP协议的网络编程
      窗体:
        img_a6216fd4e37d45880bbdf38682aba19b.jpg
img_570d1c50093cb3ffc6885e874cb082db.jpg  
      Form2做为本程序的服务器端,当按下Start后,启动服务,剩下的是一个Form1,我启动了两次,都连接到Form2,当在Form1的Send栏里写入小写字母并按下Send按钮后,将该字符串发送至Form2,同时Form2将该字符串转换为大写,返回给发送者,说明完毕,出个谜语,谁知道两个Form1里字母是啥意思?
        Form2:(服务器端)

public partial class Form2 : Form
    {

       //声明监听对象
        private TcpListener tl;

       //声明网络流
        private NetworkStream ns;
        public Form1()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();           
        }

        private void btnStart_Click(object sender, EventArgs e)
        {

            //开启8888端口的监听
            tl = new TcpListener(8888);
            tl.Start();

           //开启线程
            Thread th = new Thread(new ThreadStart(listen));
            th.IsBackground = true;
            th.Start();
        }
        private void listen()
        {           
            while (true)
            {   

               //获得响应的Socket
                Socket sock = tl.AcceptSocket();  

               //通过该Socket实例化网络流           
                ns = new NetworkStream(sock);

               //ClientTcp是添加的类,下面会做说明
                ClientTcp ct = new ClientTcp(ns);

               //ct_MyEvent方法注册ClientTcp类的MyEvent事件
                ct.MyEvent += new MyDelegate(ct_MyEvent);

               //开启线程
                Thread th = new Thread(new ThreadStart(ct.TcpThread));
                th.IsBackground = true;
                th.Start();
            }
        }

        void ct_MyEvent(string temp)
        {

           //设置服务器端TextBox的值
            this.textBox1.Text = temp;
        }
    }

 

       Form1:(客户端)

 

public partial class Form1 : Form
    {

       //声明Tcp客户端
        private TcpClient tc;

       //声明网络流
        private NetworkStream ns;
        public Form1()
        {
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {

           //注册本机8888端口
            tc = new TcpClient("localhost",8888);

           //实例化网络流对象
            ns = tc.GetStream();
            string temp = this.textBox1.Text;

            StreamWriter sw = new StreamWriter(ns);
            StreamReader sr = new StreamReader(ns);

           //将TextBox1的值传给服务器端
            sw.WriteLine(temp);
            sw.Flush();

           //接收服务器端回传的字符串
            string str = sr.ReadLine();
            this.textBox2.Text = str;
            sr.Close();
            sw.Close();
        }
    }

 

       ClientTcp类:

   //声明一个需要一个字符串参数的委托

   public delegate void MyDelegate(string temp);
    class ClientTcp
    {

       //设置网络流局部对象
        private NetworkStream ns;

       //声明类型为MyDelegate的事件MyEvent
        public event MyDelegate MyEvent;

       //构造函数中接收参数以初始化
        public ClientTcp(NetworkStream ns)
        {
            this.ns = ns;
        }

       //服务器端线程所调用的方法
        public void TcpThread()
        {

           //获得相关的封装流
            StreamReader sr = new StreamReader(ns);
            string temp = sr.ReadLine();

           //接收到客户端消息后触发事件将消息回传
            MyEvent(temp);
            StreamWriter sw = new StreamWriter(ns);

           //转换为大写后发送消息给客户端
            sw.WriteLine(temp.ToUpper());
            sw.Flush();
            sw.Close();
            sr.Close();
        }
    }

     这里说下为什么需要ClientTcp这么个类,说这个之前,先说一下为什么服务器端需要开启一个新的线程来监控端口,这个原因比较简单,Socket sock = tl.AcceptSocket();  这个方法会造成阻塞,也就是说如果没有得到客户端的响应,TcpListenr将一直监听下去,这就会造成程序的假死,因此我们需要单独开一个线程来监听我们的8888端口,我们观察服务器端(Form2)可以看出,NetworkStream是一个全局变量(实际上局部与全局都是一样),如果CPU忙的过来,直接把ClientTcp里的方法拿到Form2里写没问题,但是一旦客户端过多造成数据拥挤,那很可能当运算还未结束,NetworkStream就已经换人了,因此当我们取得某客户端对应的NetworkStream后,应该考虑立刻将它封装到一个类中,再在该类中再对该NetworkStream做相应的操作,ClientTcp这个类就是为这个设计的,而当封装了NetworkStream后,我们发现从客户端传过来的值是我们需要的,因此就用到了事件的回调,这个我前面有篇文章里讲过了,见http://blog.sina.com.cn/u/4c459776010008ws,基于TCP协议的网络编程基础的东西就这些,写法很固定,但是需要很多的技巧,前几天试着写一个聊天室程序,差点没吐血,果然不是一般的麻烦。

目录
相关文章
|
2月前
|
网络协议 安全 网络安全
什么是TCP/UDP/HTTP?它们如何影响你的内网穿透体验?
数据的传输离不开各种协议,它们就像现实世界中的交通规则,规定了数据如何打包、寻址、传输和接收。对于使用内网穿透的用户来说,理解TCP、UDP和HTTP这些基础协议的特点,能帮助你更好地理解其性能表现,并选择最适合的配置方案。
|
4月前
|
网络协议 安全 网络安全
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
430 2
|
4月前
|
网络协议 开发者
探讨UDP协议中connect函数的作用及影响
总结来看,虽然UDP是无连接的,`connect()` 函数的使用在UDP编程中是一种可选的技术,它可以带来编程上的便利和某些性能上的改进,同时它改变的是程序逻辑上的行为,而非UDP协议本身的无连接特性。在实际应用中,根据通信模式和需求的不同,开发者可以根据情况选择是否调用 `connect()` 函数。
224 8
|
6月前
|
监控 网络协议 视频直播
UDP协议(特点与应用场景)
UDP(用户数据报协议)是传输层的一种无连接协议,具有简单高效、低延迟的特点。其主要特点包括:无连接(无需握手)、不可靠传输(不保证数据完整性)、面向数据报(独立传输)。尽管UDP不如TCP可靠,但在实时通信(如语音通话、视频会议)、在线游戏、多媒体流媒体(如直播、点播)及网络监控等领域广泛应用,满足了对速度和实时性要求较高的需求。
1119 19
|
7月前
|
网络协议
为何UDP协议不可靠?DNS为何选择UDP?
总的来说,UDP和TCP各有优势,选择哪种协议取决于应用的具体需求。UDP可能不如TCP可靠,但其简单、快速的特性使其在某些场景下成为更好的选择。而DNS就是这样的一个例子,它利用了UDP的优势,以实现快速、高效的名字解析服务。
418 14
|
7月前
|
网络协议
TCP/IP与OPC协议的深度比较
总的来说,TCP/IP和OPC协议各有其优点和应用场景。TCP/IP协议是网络通信的基础,而OPC协议则是工业自动化领域的重要工具。在实际应用中,我们需要根据具体的需求和场景,选择合适的协议。
275 11
|
7月前
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
445 1
|
8月前
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
317 12
|
10月前
|
缓存 网络协议
Jmeter如何对UDP协议进行测试?
`jmeter-plugins`是JMeter的插件管理器,用于管理和组织所有插件。访问[官网](https://jmeter-plugins.org/install/Install/)下载并放置于`lib/ext`目录下,重启JMeter后可在“选项”中看到插件管理器。
363 1
Jmeter如何对UDP协议进行测试?
|
9月前
|
网络协议 算法 安全
Go语言的网络编程与TCP_UDP
Go语言由Google开发,旨在简单、高效和可扩展。本文深入探讨Go语言的网络编程,涵盖TCP/UDP的基本概念、核心算法(如滑动窗口、流量控制等)、最佳实践及应用场景。通过代码示例展示了TCP和UDP的实现,并讨论了其在HTTP、DNS等协议中的应用。最后,总结了Go语言网络编程的未来发展趋势与挑战,推荐了相关工具和资源。
294 5

热门文章

最新文章

下一篇
oss云网关配置