Socket网络通讯
网络编程
使用C#进行网络编程时,通常都需要用到System.Net命名空间、System.Net.Sockets命名空间和System.Net.Mail命名空间;
1. System.Net命名空间:为当前网络上使用的多种协议提供了简单的编程接口。
- DNS类:DNS是一个静态类,它从Internet域名系统(DNS)检索关于特定主机的信息,在IPHostEntry类的实例中返回来自DNS查询的主机信息。(GetHostName()找到本地系统的主机名,然后再用GetHostByName()找到主机的IP地址)
- IPAddress类:包含计算机在IP网络上的地址,主要用来提供网际协议(IP)地址。
- IPEndPoint类包含应用程序连接到主机上的服务所需要的主机和本地或远程端口信息。主要用来将网络端点表示为IP地址和端口号。
- WebClient类:提供向URL标识的任何本地、Intranet或Internet资源发送数据以及从这些资源接收数据的公共方法。
- WebRequest类:.Net Framework的请求/响应模型的抽象基类,用于访问Internet数据。使用该请求/响应模型的应用程序可以用协议不可知的方式从Internet请求数据。
2. System.Net.Sockets命名空间:
主要提供制作Sockets网络应用程序的相关类,其中Socket类,TcpClient类、TcpListener类和UdpClient类较为常用。在.NET框架下开发时,直接使用System.Net.Sockets名称空间中的Socket类编程较为复杂,而应用层的类TcpClient、TcpListener 和 UdpClient为 Socket 通信提供了更简单、对用户更友好的接口。它们和Socket类之间的这种层次关系如图

(1)Socket类:主要用于管理连接(将应用程序与端口连接起来,端口是一台计算机的数据都通过此连接网络, Socket是基于流套接字协议(TCP协议)/基于数据报套接字协议(UDP协议)最为通用的API。),实现Berkeley通信端套接字接口,同时它还定义了绑定、连接网络端点及传输数据所需的各种方法。
- void Bind(IPEndPoint localEP):绑定地址,使Socket与一个本地终节点相关联。
- Void Connect(IPEndPoint ip):建立连接
- Void Listen(int backlog):将Socket置于侦听状态, backlog最多可连接数。
- Int Receive(byte[] buffer):接收数据
- Int Receive (byte[] buffer,ref IPEndPoint ip):从指定地址接收数据
- Int Send(byte[] buffer):发送数据
- Int Send To(byte[] buffer,ref IPEndPoint remoteIP):向指定地址发送数据
- Void Shutdown(SocketShutdown how):关闭套接字,how指定不在允许执行的操作
注:使用accept函数建立新的连接时,并不是使用原来的Socket进行通信,而是返回一个新的Socket套接字进行连接通信。原来的Socket继续进入监听状态,等待他人的连接要求。
(2)TcpClient类:基于Socket类构建,用于在同步阻止模式下通过网络来连接,发送,接收数据。
这是它能够以更高的抽象程度提供TCP服务的基础。体现在网络数据的发送和接受方面,是TcpClient使用NetworkStream网络流处理技术,使得它读写数据更加方便直观。TcpClient类专为客户端设计,它为 TCP 网络服务提供客户端连接。
(3)NetworkStream网络流:可以被视为一个数据通道,架设在数据来源端(客户Client)和接收端(服务Server)之间,通过TcpClient.GetStream方法,返回用于发送和接收数据的网络流NetworkStream。
注:要创建NetworkStream必须提供连接的Socket.默认情况下关闭NetworkStream并不会关闭所提供的Socket.如果要关闭Socket权限,则必须将ownsSocket构造函数参数的值指定为true.而后的数据读取及写入均针对这个通道来进行。不支持对网络流的随机访问。
示例如下:通过以下方法得到NetworkStream网络流之后,就可以使用标准流读写方法Write和Read来发送和接受数据了。
TcpClient tcpClient = new TcpClient(); //创建TcpClient对象实例
tcpClient.Connect("www.baidu.com",); //尝试与远程主机相连
NetworkStream stream=tcpClient.GetStream(); //获取网络传输流
- BeginRead():从NetworkStream开始一步读取
- BeginWrite():开始向流异步写入
- Close():关闭NetworkStream
- EndRead():处理异步读取结束
- EndWrite():处理异步写入结束
- Flush():刷新流中的数据
- Read():从流中读取
- ReadByte():从流中读取一个字节,并将流内的位置向前推进一个字节。到达末尾,返回-1。
- Write():将数据写入NetworkStream
- WriteByte():将一个字节写入流内的当前位置,并将流内的位置向前推进一个字节。
Server:获取基础网络Socket
- AcceptSocket/AcceptTcpClient:接受挂起的连接请求
- BeginAcceptSocket/BeginAcceptTcpClient:开始一个异步操作来接受一个传入的连接尝试
- Start:开始侦听传入的连接请求
- Stop:关闭侦听
Client客户端连接侦听器的两种方法:
(1)创建一个TcpClient,并调用3个可用Connect方法之一。
(2)使用远程主机的主机名和端口号创建TcpClient,此构造函数将自动尝试一个连接。
- Client:获取或设置基础Socket
- ReceiveBufferSize:获取或设置接收缓冲区的大小
- SendBufferSize:获取或设置发送缓冲区的大小
- BeginConnect方法:开始一个对远程主机连接的异步请求
- Close:释放TcpClient 实例,不关闭基础连接
- Connect:使用指定的主机名和端口号将客户端连接到TCP主机
- GetStream:返回用于发送和接收数据的NetworkStream
创建连接TCPClient连接方法:
(1)创建一个TcpClient,并调用三个可用的Connect()方法之一。
- void Connect(IPEndPoint):使用指定的远程网络节点将客户端连接到远程TCP主机。
IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList();//获取IP地址
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 60000);//设置端口
TcpClient tcpClientA = new TcpClient(ipLocalEndPoint);//创建客户端
2. void Connect(IPAddress,int):使用指定的IP地址和端口号将客户端连接到TcpClient主机。
3. void Connect(string,int):将客户端连接到指定主机上的指定端口。
TcpClient tcpClientB = new TcpClient("www.baidu.com", );//创建客户端
(2) 使用远程主机的主机名和端口号创建TcpClient。
TcpClient tcpClient = new TcpClient();//创建TcpClient对象实例
tcpClient.Connect("www.baidu.com",);//建立连接
注:要发送和接受数据,先使用GetStream()方法来获取一个NetworkStream,再调用NetworkStream的Write()和Read()方法与远程主机之间发送和接收数据。最后使用Close()方法释放与TcpClient()关联的所有资源。
TcpListner:用于阻止同步模式下侦听和接受传入的连接请求。
可使用TcpClient类或Socket类来连接TcpListener,并且可以使用IPEndPoint、本地IP地址及端口号来创建TcpListener实例对象。
.Net中的TcpListener主要作用是监视TCP端口上客户端的请求,通过绑定本机IP地址和相应端口创建TcpListener对象实例,并由Start方法启动侦听;当TcpListener侦听到用户端的连接后,通过AcceptTcpClient方法接受传入的连接请求并创建TcpClient以处理请求,或者通过AcceptSocket方法接受传入的连接请求并创建Socket以处理请求。
(1)创建服务器端:
//建立TCP监听器TcpListener对象。
TcpListener tl=new TcpListener(端口号);
//启动监听器
tl.Start();
//用监听器获取连接进来的套接字(Socket)
Socket s=myList.AcceptSocket();
//通过Socket的Receive方法获取客户端发送的数据
byte [] result=new byte[];
int k=s.Receive(result);
//通过Socket的Send方法向客户端发送数据
byte[] st=System.Text.Encoding.Default.GetBytes(“text”);
s.Send(st);
//在通讯结束后,需要释放资源结束监听
s.Close();
tl.Stop();
Socket建立服务器:初始化监听Socket 接受新的客户端连接 收发数据 关闭连接
socketServer = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//创建Socket 客户端
//Socket绑定本地端口监听客户端连接;
Socket.Bind(端口号);
Socket.Listen();
socket.Receive();//创建连接的客户端的Socket并开启线程接收数据;
socket.Send();//发送数据
socket.Close();//关闭连接
TcpClient创建客户端:
//建立TCP客户端TcpClient对象。
TcpClient tcpclnt = new TcpClient();
//连接服务器
tcpclnt.Connect(IP地址字符串,端口号);
//获得客户端网络传输 流
Stream stm =tcpclnt.GetStream();
//通过Stream的Write方法向服务器端发送的数据
//通过Stream的Read方法读取服务器段发来的数据
//在通讯结束后,需要释放资源,结束和服务器的连接
tcpclnt.Close();
TCP与UDP的区别
- TCP是面向连接的服务、UDP是面向无连接服务
- TCP是具有差错控制的,而UDP没有缺乏可靠性
- TCP的传输是有序的,UDP是无序的
- UDP的实时性更好,有简单,快速、占用资源少的优点。
- UDP传输限定在64KB之内,Tcp一旦建立连接,就可以按统一的格式传输大量的数据。
使用UdpClient类实现UDP协议编程
由于UDP协议并不需要进行确定的连接,程序中可以不需要考虑连接和一些异常的捕获工作。在有些对数据安全性要求不是很高的情况下采用UDP协议。
在System.Net.Sockets命名空间下的UdpClient类,提供更直观的易于使用的属性和方法,从而降低UDP编程的难度。使用UdpClient时,连接的客户端需要先发送一个信息给服务器,服务器才能和客户端通讯。
UdpClient类的构造函数有以下几种格式:
UdpClient();
UdpClient(int port);
UdpClient(IPEndPoint iep);
UdpClient(string remoteHost,int port);
利用Socket编写UdpClient
Socket udpSocket;//创建Socket
udpSocket.Bind(IPAddress,IPEndPoint);//把Socket绑定本地IP和端口号
//开启线程接收信息:先保存接到信息的端口号,使用ReceiveFrom发送信息
EndPoint point = new IPEndPoint(IPAddress.Any, );//用来保存发送方的ip和端口号
EndPoint point = (EndPoint)IPEndPoint;
//发送信息:使用EndPoint创建发送目标的IP和端口号;
//关闭线程和Socket
利用UDPClient编程
//建立UDP客户端UdpClient对象。
UdpClient uc=new UdpClient(端口号);
//连接对方远程主机
uc.Connect(对方IP地址,对方远程主机的端口号);
//开启线程,通过uc的Receive方法获取远程主机发送来的数据
IPEndPoint ip=new IPEndPoint(IPAddress.Any,);
byte[] b=uc.Receive(ref ip);
//通过uc的Send方法向远程主机发送数据
byte[] st=System.Text.Encoding.Default.GetBytes(“text”);
uc.Send(st);
//在通讯结束后,需要释放资源
uc.Close();
Socket网络通讯的更多相关文章
- Socket网络通讯开发总结之:Java 与 C进行Socket通讯 + [备忘] Java和C之间的通讯
Socket网络通讯开发总结之:Java 与 C进行Socket通讯 http://blog.sina.com.cn/s/blog_55934df80100i55l.html (2010-04-08 ...
- [dotnet core]使用Peach简化Socket网络通讯协议开发
Peach是基于DotNetty的Socket网络通讯帮助类库,可以帮助开发者简化使用DotNetty,关于DotNetty可参考我之前的这篇文章. Peach内置实现了一个基于文本协议的Comman ...
- Socket网络通讯开发总结之:Java 与 C进行Socket通讯(转)
先交待一下业务应用背景:服务端:移动交费系统:基于C语言的Unix系统客户端:增值服务系统:基于Java的软件系统通迅协议:采用TCP/IP协议,使用TCP以异步方式接入数据传输:基于Socket流的 ...
- [转] C#.Net Socket网络通讯编程总结
1.理解socket1).Socket接口是TCP/IP网络的应用程序接口(API).Socket接口定义了许多函数和例程,程序员可以用它们来开发TCP/IP网络应用程序.Socket可以看成是网络通 ...
- MFC socket网络通讯核心代码
服务器: AfxSocketInit();//初始化,必须执行这个函数socket才能正常执行 server.Create(10086); server.Listen(10); while(1) { ...
- bsd socket 网络通讯必备工具类
传输数据的时候都要带上包头,包头有简单的又复杂的,简单的只要能指明数据的长度就够了. 这里我写了一个工具类,可以方便地将整型的数据长度转换为长度为 4 的字节数组. 另一方面,可以方便的将长度为 4 ...
- C#.NET通过Socket实现平行主机之间网络通讯(含图片传输的Demo演示)
在程序设计中,涉及数据存储和数据交换的时候,不管是B/S还是C/S模式,都有这样一个概念:数据库服务器.这要求一台性能和配置都比较好的主机作为服务器,以满足数目众多的客户端进行频繁访问.但是对于一些数 ...
- dicom网络通讯入门(2)
第二篇,前面都是闲扯 其实正文现在才开始,这次是把压箱底的东西都拿出来了. 首先我们今天要干的事是实现一个echo响应测试工具 也就是echo 的scu,不是实现打印作业管理么.同学我告诉你还早着呢. ...
- Windows 网络通讯开发
Windows 网络通讯开发 一.Windows网络开发API 由于C++标准库中没有网络库,所以进行网络开发的时候要调用系统API.Windows通讯开发API包括以下几个基本函数及成员类型: 1. ...
随机推荐
- 如何用FFmpeg API采集摄像头视频和麦克风音频,并实现录制文件的功能
之前一直用Directshow技术采集摄像头数据,但是觉得涉及的细节比较多,要开发者比较了解Directshow的框架知识,学习起来有一点点难度.最近发现很多人问怎么用FFmpeg采集摄像头图像,事实 ...
- java代码反转toCharAT()的用法
总结:反转注意for循环里面的变化 package clientFrame; //字符串反转 public class we { public static void main(String[] ar ...
- thinkphp中的_initialize方法
子类的_initialize方法自动调用父类的_initialize方法.而php的构造函数construct,如果要调用父类的方法,必须在子类构造函数显示调用parent::__construct( ...
- from表单
构建一个表单 假设你想在你的网站上创建一个简单的表单,以获得用户的名字.你需要类似这样的模板: 1 2 3 4 5 <form action="/your-name/" me ...
- python's eighth day for me
f : 变量,f_obj, file, f_handler,...文件句柄. open : windows 的系统功能. windows 默认编码方式:gbk. Linux 默认编码方式:utf ...
- java成神之——MySQL Connector/J 的基本使用
使用示例 DBCP连接池 结语 使用示例 public class demo { static Connection con = null; static Statement st = null; s ...
- leetcode486
public class Solution { public bool PredictTheWinner(int[] nums) { // int n = nums.Length; // int[,] ...
- redis-win7
http://blog.csdn.net/renfufei/article/details/38474435
- POJ1657
1.题目链接地址 http://poj.org/problem?id=1657 2.源代码 #include<iostream> using namespace std; int main ...
- 通过class类获取类的成员变量和构造函数信息