[转贴]基于UDP、TCP协议的C#网络编程之二
2010-03-18 14:33
736 查看
转自新浪"烈·翼·焚·天"的博客,原文地址:http://blog.sina.com.cn/s/blog_4c459776010009c3.html~type=v5_one&label=rela_nextarticle
第二截,讲讲基于TCP协议的网络编程,与UDP不同的是,基于TCP协议的编程的服务器端有一个监听对象:TcpListener,它负责监听来自客户端的消息并处理,并且必须在保持连接的情况下与客户端保持互动,下面举个例子,TCP不怎么复杂,只是综合要求较高,如果想编出个象样的东西,对多线程,事件委托等等都需要有较高的认识,当然,还要对协议本身有深刻的理解。咱水平不到,来个课堂实例。
示例一:基于TCP协议的网络编程
窗体:
Form2做为本程序的服务器端,当按下Start后,启动服务,剩下的是一个Form1,我启动了两次,都连接到Form2,当在Form1的Send栏里写入小写字母并按下Send按钮后,将该字符串发送至Form2,同时Form2将该字符串转换为大写,返回给发送者,说明完毕,出个谜语,谁知道两个Form1里字母是啥意思?
Form2:(服务器端)
Form1:(客户端)
ClientTcp类:
这里说下为什么需要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协议的网络编程基础的东西就这些,写法很固定,但是需要很多的技巧,前几天试着写一个聊天室程序,差点没吐血,果然不是一般的麻烦。
第二截,讲讲基于TCP协议的网络编程,与UDP不同的是,基于TCP协议的编程的服务器端有一个监听对象:TcpListener,它负责监听来自客户端的消息并处理,并且必须在保持连接的情况下与客户端保持互动,下面举个例子,TCP不怎么复杂,只是综合要求较高,如果想编出个象样的东西,对多线程,事件委托等等都需要有较高的认识,当然,还要对协议本身有深刻的理解。咱水平不到,来个课堂实例。
示例一:基于TCP协议的网络编程
窗体:
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; } } |
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(); } } |
//声明一个需要一个字符串参数的委托 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(); } } |
相关文章推荐
- [转贴]基于UDP、TCP协议的C#网络编程之一
- 【转载】 基于UDP、TCP协议的C#网络编程
- 基于UDP、TCP协议的C#网络编程之一
- 基于UDP、TCP协议的C#网络编程之一
- 【转载】 基于UDP、TCP协议的C#网络编程
- 基于UDP、TCP协议的C#网络编程之二
- 【转载】 基于UDP、TCP协议的C#网络编程
- 基于UDP、TCP协议的C#网络编程
- 基于UDP协议的C#网络编程
- 使用C#实现基于TCP和UDP协议的网络通信程序的基本示例
- Windows套接字编程:基于TCP和UDP协议
- 基于UDP协议的网络编程
- java 网络编程 基于TCP ,UDP的网络传输
- 基于TCP,UDP的网络编程总结
- [置顶] 基于iOS的网络音视频实时传输系统(四)- 自定义socket协议(TCP、UDP)
- Python网络编程之TCP与UDP协议套接字用法示例
- python(12-2 网络编程 udp ,tcp 协议)
- 用C#设计一个基于UDP协议的简单网络聊天器
- 基于 TCP (面向连接)和无连接UDP协议的 socket 套接字编程
- {网络编程}和{多线程}应用:基于UDP协议【实现多发送方发送数据到同一个接收者】--练习