用C#实现基于TCP协议的网络通讯
TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程。然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序。
要进行基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分——主机名和端口,如www.yesky.com:80中,www.yesky.com就是主机名,80指主机的80端口,当然,主机名也可以用IP地址代替。当连接建立之后,就可以使用这个连接去发送和接收数据包,TCP协议的作用就是保证这些数据包能到达终点并且能按照正确的顺序组装起来。
在.net framework的类库(Class Library)中,提供了两个用于TCP网络通讯的类,分别是TcpClient和TcpListener。由其英文意义显而易见,TcpClient类是基于TCP协议的客户端类,而TcpListener是服务器端,监听(Listen)客户端传来的连接请求。TcpClient类通过TCP协议与服务器进行通讯并获取信息,它的内部封装了一个Socket类的实例,这个Socket对象被用来使用TCP协议向服务器请求和获取数据。因为与远程主机的交互是以数据流的形式出现的,所以传输的数据可以使用.net framework中流处理技术读写。在我们下边的例子中,你可以看到使用NetworkStream类操作数据流的方法。
在下面的例子中,我们将建立一个时间服务器,包括服务器端程序和客户端程序。服务器端监听客户端的连接请求,建立连接以后向客户端发送当前的系统时间。
先运行服务器端程序,下面截图显示了服务器端程序运行的状况:
然后运行客户端程序,客户端首先发送连接请求到服务器端,服务器端回应后发送当前时间到客户端,这是客户端程序的截图:
发送完成后,服务器端继续等待下一次连接:
通过这个例子我们可以了解TcpClient类的基本用法,要使用这个类,必须使用System.Net.Socket命名空间,本例用到的三个命名空间如下:
using System;
using System.Net.Sockets;
using System.Text;//从字节数组中获取字符串时使用该命名空间中的类
首先讨论一下客户端程序,开始我们必须初始化一个TcpClient类的实例:
TcpClient client = new TcpClient(hostName, portNum);
然后使用TcpClient类的GetStream()方法获取数据流,并且用它初始化一个NetworkStream类的实例:
NetworkStream ns = client.GetStream();
注意,当使用主机名和端口号初始化TcpClient类的实例时,直到跟服务器建立了连接,这个实例才算真正建立,程序才能往下执行。如果因为网络不通,服务器不存在,服务器端口未开放等等原因而不能连接,程序将抛出异常并且中断执行。
建立数据流之后,我们可以使用NetworkStream类的Read()方法从流中读取数据,使用Write()方法向流中写入数据。读取数据时,首先应该建立一个缓冲区,具体的说,就是建立一个byte型的数组用来存放从流中读取的数据。Read()方法的原型描述如下:
public override int Read(in byte[] buffer,int offset,int size)
buffer是缓冲数组,offset是数据(字节流)在缓冲数组中存放的开始位置,size是读取的字节数目,返回值是读取的字节数。在本例中,简单地使用该方法来读取服务器反馈的信息:
byte[] bytes = new byte[1024];//建立缓冲区
int bytesRead = ns.Read(bytes, 0, bytes.Length);//读取字节流
然后显示到屏幕上:
Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead));
最后不要忘记关闭连接:
client.Close();
下面是本例完整的程序清单:
using System;
using System.Net.Sockets;
using System.Text;
namespace TcpClientExample
{
public class TcpTimeClient
{
private const int portNum = 13;//服务器端口,可以随意修改
private const string hostName = "127.0.0.1";//服务器地址,127.0.0.1指本机
[STAThread]
static void Main(string[] args)
{
try
{
Console.Write("Try to connect to "+hostName+":"+portNum.ToString()+"/r/n");
TcpClient client = new TcpClient(hostName, portNum);
NetworkStream ns = client.GetStream();
byte[] bytes = new byte[1024];
int bytesRead = ns.Read(bytes, 0, bytes.Length);
Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead));
client.Close();
Console.ReadLine();//由于是控制台程序,故为了清楚的看到结果,可以加上这句
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
上面这个例子清晰地演示了客户端程序的编写要点,下面我们讨论一下如何建立服务器程序。这个例子将使用TcpListener类,在13号端口监听,一旦有客户端连接,将立即向客户端发送当前服务器的时间信息。
TcpListener的关键在于AcceptTcpClient()方法,该方法将检测端口是否有未处理的连接请求,如果有未处理的连接请求,该方法将使服务器同客户端建立连接,并且返回一个TcpClient对象,通过这个对象的GetStream方法建立同客户端通讯的数据流。事实上,TcpListener类还提供一个更为灵活的方法AcceptSocket(),当然灵活的代价是复杂,对于比较简单的程序,AcceptTcpClient()已经足够用了。此外,TcpListener类提供Start()方法开始监听,提供Stop()方法停止监听。
首先我们使用端口初始化一个TcpListener实例,并且开始在13端口监听:
private const int portNum = 13;
TcpListener listener = new TcpListener(portNum);
listener.Start();//开始监听
如果有未处理的连接请求,使用AcceptTcpClient方法进行处理,并且获取数据流:
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
然后,获取本机时间,并保存在字节数组中,使用NetworkStream.Write()方法写入数据流,然后客户端就可以通过Read()方法从数据流中获取这段信息:
byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
ns.Write(byteTime, 0, byteTime.Length);
ns.Close();//不要忘记关闭数据流和连接
client.Close();
服务器端程序完整的程序清单如下:
using System;
using System.Net.Sockets;
using System.Text;
namespace TimeServer
{
class TimeServer
{
private const int portNum = 13;
[STAThread]
static void Main(string[] args)
{
bool done = false;
TcpListener listener = new TcpListener(portNum);
listener.Start();
while (!done)
{
Console.Write("Waiting for connection...");
TcpClient client = listener.AcceptTcpClient();
Console.WriteLine("Connection accepted.");
NetworkStream ns = client.GetStream();
byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
try
{
ns.Write(byteTime, 0, byteTime.Length);
ns.Close();
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
listener.Stop();
}
}
}
把上面两段程序分别编译运行,OK,我们已经用C#实现了基于TCP协议的网络通讯,怎么样?很简单吧!
使用上面介绍的基本方法,我们可以很容易的编写出一些很有用的程序,如FTP,电子邮件收发,点对点即时通讯等等,你甚至可以自己编制一个QQ来!
用C#实现基于TCP协议的网络通讯相关推荐
- 用C#实现基于TCP协议的网络通讯(2)
2008-09-09 19:36 作者: 出处:www.4oa.com ( 11 ) 砖 ( 12 ) 好 评论 ( 0 ) 条 进入论坛 更新时间:2005-09-29 14:54 关 键 词 ...
- 用C#实现基于TCP协议的网络通讯(1)
2008-09-09 19:35 作者: 出处:www.4oa.com ( 11 ) 砖 ( 12 ) 好 评论 ( 0 ) 条 进入论坛 更新时间:2005-09-29 14:54 关 键 词 ...
- 基于TCP协议的网络摄像头的设计与实现
一.摘要 基于TCP协议的网络摄像头的设计大部分和博文"基于UDP协议的网络摄像头的设计与实现"相同,本篇博文采用的TCP协议栈为NicheStack协议栈(同理,可使用LWIP协 ...
- 篡改计算机网络,基于TCP协议的网络数据实时篡改.doc
基于TCP协议的网络数据实时篡改 基于 TCP 协议的网络数据实时篡改 金 瓯,施 勇,薛 质(上海交通大学信息安全工程学院,上海 200240)[摘 要]首先对网络数据实时篡改作了定义,指出攻击者介 ...
- 基于TCP协议的网络聊天室
创建服务端程序 public class Server {public static void main(String[] args) {new Thread(new ServerTask()).st ...
- 基于TCP协议的网络程序(基础学习)
下图是基于TCP协议的客户端/服务器程序的一般流程: 图 37.2. TCP协议通讯流程 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听 ...
- c语言tcp硬时事通讯程序代码,使用C语言编写基于TCP协议的Socket通讯程序实例分享...
tcp客户端示例 #include #include #include #include #include #include #include #include #include #include # ...
- 浅析C#基于TCP协议的SCOKET通信
TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实 ...
- step5 . day2 网络编程 基于TPC协议的网络编程流程及API
基于TCP协议的网络编程流程 服务器端: 1) socket(),创建套接字文件,用于连接 2) bind(), 绑定,把socket()函数返回的文件描述符和IP.端口号进行绑定; 3) liste ...
最新文章
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第五步--button控制主角Jumpamp;Crouch
- 为什么eolinker发送老是等待_如何妙用 eoLinker 进行接口测试
- MySQL性能优化(八)
- android 沉浸式状态栏的三种方法
- 【分享】Oracle 常用运维命令大全
- iPhone X适配小结
- python导入模块--案例
- 干货 | 数据挖掘过关40题
- 大一计算机课实训总结1000字,大一计算机实训报告.doc
- python--multiprocessing多进程总结
- Diablo II中的各种hacks
- 微软模拟飞行10厦门航空涂装_《微软飞行模拟》或很快迎来技术公测
- tomcat的Server.xml详解和Host的配置
- 闪耀在 UNIX 传奇往事中的启示, UNXI 见证者带你一览究竟
- pyttsx3 快速上手之:语音合成播报
- 利用WinPcap模拟网络包伪造飞秋闪屏报文
- 如何安装idea社区版
- PGP 对于JSON的加解密
- html改变按钮水平位置,div中button水平居中
- 数据结构——冒泡排序
热门文章
- java set 包含_Java Set.contains()方法:判断Set集合是否包含指定的对象
- l开头的英文车标是什么车_汽车品牌车标大全,有哪些品牌的车标你没见过?...
- php将数组最后一个单元弹出,php array_pop()数组函数将数组最后一个单元弹出(出栈)...
- mysql shharding_mysql 技术内幕 的示例数据库
- 使用Python,OpenCV进行形态学操作
- 机器学习中的数学基础:(1)实际应用中矩阵特征值与特征向量的几何意义
- 【机器视觉案例】(8) AI视觉,手势控制电脑鼠标,附python完整代码
- trainer setup_Detectron2源码阅读笔记-(一)Configamp;Trainer
- centos 6.8 x86_64下autoconf版本升级到2.69
- 完整的虚幻引擎超级课程:从初学者到专家