当前位置:文档之家› 使用套接字Socket实现网络通信

使用套接字Socket实现网络通信

使用套接字Socket实现通信
一对一的通信:

一、通信基础:
首先我们要在双方建立连接,那么我们如何在两台电脑上的应用程序建立连接通道?
我们可以从以下得到启示:
1、唯一标识网络中的主机:“网络层的‘IP地址’”;
2、唯一标识主机中的应用程序:“传输层的‘IP地址+端口号’”
其次我们需要一套共同的语言来交流:也就是协议
我们可以采用我们熟悉:TCP/IP协议;

连接建立了,共同语言也有了,接下来就需要实现一些操作
这里我们采用的技术是:Socket套接字技术

首先,需要引用的命名空间:
using https://www.doczj.com/doc/7c9343953.html,.Sockets;
using https://www.doczj.com/doc/7c9343953.html,;
using System.Threading; //多线程

使用Socket套接字技术时:可以用两种方式建立连接:同步传输和异步传输
同步传输:
当监听端口接收到多个连接时需要排队,因为在这个端口下如果同是来了两个客户端请求,第一个连接得到响应,与服务端建立通讯,
而第二个请求就会被一直阻塞直到第一个请求完成操作,各个请求之间就好像排个队,顺序执行,这就是同步。
异步传输:
就是同时来两个或者多个请求,服务端就同时响应多个客户端,同时给他们连接。
各个客户端与服务器的通讯是并行的,一个客户端不必等另一个客户端完成操作。

在这里我们使用同步传输:
用到的类:
(1)Socket类
构造函数:初始化Socket对象:public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
该类用到的方法:
1、绑定IP和端口号:Bind()
2、监听IP和端口号:Listen()
3、当接收到连接请求时新建连接创建新的Socket对象并作为返回值:Accept()
4、对处于监听的IP和端口发出连接请求:Connect()
5、用以两个Socket对象的信息交流:接收信息:Receive()和发送信息Send()
(2)Threat类:
由于在通信期间,接收信息需要一直处于运作状态,这时程序处于假死,无法进行其他操作;
所以我们需要引入多线程技术:接收信息的同时,还可以进行其他操作。
构造函数:初始化Threat对象,参数位,要执行的方法:public Thread(ThreadStart start);
该类用到的方法:
1、线程开始运作:Start()
该类用到的属性:
1、是否后台运作:IsBackground

二、运作过程:
服务端:
创建Socket对象,同时获取IP和端口号;
获取的IP存储在IPAddress类:
演示:IPAddress ip=IPAddress.Parse("127.0.0.1");
获取的IP和端口号存储在IPEndPoint类
演示:IPEndPoint point = new IPEndPoint(ip, int.Parse(“5000”));
实例化Socket创建的对象;
演示:Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
绑定并

且监听:
演示:socketListen.Bind(point); socketListen.Listen(10);
接收连接请求并返回一个新的Socket对象:
演示:Socket newsocket= socketListen.Accept();
用新的Socket对象进行收发信息:
接收信息,返回值是信息的长度,参数是字节流:
演示:byte[] buffer = new byte[1024 * 1024]; int n= newsocket.Receive(buffer);接收的信息存储在buffer的数组里
注意:由于演示,接收信息这块没有使用多线程,在实际应用中,多线程是必须的。
发信息:
演示:byte[] buffer = Encoding.UTF8.GetBytes(“你要发送的信息!”); newsocket.Send(buffer);

客服端:
与服务端一样:
获取的IP存储在IPAddress类:
演示:IPAddress ip=IPAddress.Parse("127.0.0.1");
获取的IP和端口号存储在IPEndPoint类
演示:IPEndPoint point = new IPEndPoint(ip, int.Parse(“5000”));
实例化Socket创建的对象;
演示:Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
当服务端开始监听端口是,发起连接:
演示:socketClient.Connect(point);注意:这里的IP和端口号是服务端监听的IP和端口号
连接之后就与服务端一样收发信息:
接收信息,返回值是信息的长度,参数是字节流:
演示:byte[] buffer = new byte[1024 * 1024]; int n= socketClient.Receive(buffer);接收的信息存储在buffer的数组里
注意:由于演示,接收信息这块没有使用多线程,在实际应用中,多线程是必须的。
发信息:
演示:byte[] buffer = Encoding.UTF8.GetBytes(“你要发送的信息!”); socketClient.Send(buffer);

三、以下是上面用到的关于Socket的一些详细内容:(你也可以在在编辑程序中转到定义去看)
3.1 构造Socket()函数
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
(1)domain:协议域或协议族,指定socket的地址类型 采用: AddressFamily.InterNetwork
(2)type:指定socket的类型:采用:SocketType.Stream
(3)protecol:指定协议:(TCP传输协议,UDP传输协议,STCP传输协议,TIPC传输协议)这里采用ProtocolType.Tcp
三个参数都是枚举类
3.2 Bind()函数
public void Bind(EndPoint localEP);
// 将网络端点表示为 IP 地址和端口号。
public class IPEndPoint : EndPoint{……}
功能:把地址绑定到socket
IPEndPoint:存储端口号和IP地址的对象
使用规则:

3.3 Listen()、Connect()函数
Listen()
功能: 将 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 置于侦听状态。
public void Listen(int backlog);
参数:
// backlog:
// 挂起连接队列的最大长度。
//
异常:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.SocketException:
// 试图访问套接字时发生错误。 有关更多信息,请参见备注部分


//
// System.ObjectDisposedException:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 已关闭。

3.4 Accept()和Connect()函数

3.4.1 Accept()函数
public Socket Accept();
作用:为新建连接创建新的 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket。
返回结果:
新建连接的 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket。
异常:
https://www.doczj.com/doc/7c9343953.html,.Sockets.SocketException:
试图访问套接字时发生错误。 有关更多信息,请参见备注部分。
System.ObjectDisposedException:
https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 已关闭。
System.InvalidOperationException:
正在接受的套接字不会侦听连接。
注意:
在调用 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket.Accept()
之前必须调用 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket.Bind(https://www.doczj.com/doc/7c9343953.html,.EndPoint)
和 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket.Listen(System.Int32)。

3.4.2 Connect()函数
public void Connect(EndPoint remoteEP);
作用:建立与远程主机的连接。
参数:
remoteEP:
https://www.doczj.com/doc/7c9343953.html,.EndPoint,表示远程设备。
异常:
System.ArgumentNullException:
remoteEP 为 null。

// https://www.doczj.com/doc/7c9343953.html,.Sockets.SocketException:
// 试图访问套接字时发生错误。 有关更多信息,请参见备注部分。
//
// System.ObjectDisposedException:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 已关闭。
//
// System.Security.SecurityException:
// 调用堆栈上部的调用方无权执行所请求的操作。
//
// System.InvalidOperationException:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 为 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket.Listen(System.Int32)。

3.5 Receive()和Send()函数
3.5.1 Receive()函数
public int Receive(byte[] buffer);
作用:从绑定的 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 套接字接收数据,将数据存入接收缓冲区。
//
// 参数:
// buffer:
// System.Byte 类型的数组,它是存储接收到的数据的位置。
//
// 返回结果:
// 接收到的字节数。
//
// 异常:
// System.ArgumentNullException:
// buffer 为 null。
//
// https://www.doczj.com/doc/7c9343953.html,.Sockets.SocketException:
// 试图访问套接字时发生错误。 有关更多信息,请参见备注部分。
//
// System.ObjectDisposedException:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 已关闭。
//
// System.Security.SecurityException:
// 调用堆栈中的调用方没有所需的权限。
3.5.2 Send()函数
public int Send(byte[] buffer);
//
// 摘要:
// 将数据发送到连接的 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket。
//
// 参数:
// buffer:
//

System.Byte 类型的数组,它包含要发送的数据。
//
// 返回结果:
// 已发送到 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 的字节数。
//
// 异常:
// System.ArgumentNullException:
// buffer 为 null。
//
// https://www.doczj.com/doc/7c9343953.html,.Sockets.SocketException:
// 试图访问套接字时发生错误。 有关更多信息,请参见备注部分。
//
// System.ObjectDisposedException:
// https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 已关闭。

3.6 Close()函数
//
// 摘要:
// 关闭 https://www.doczj.com/doc/7c9343953.html,.Sockets.Socket 连接并释放所有关联的资源。
public void Close();

相关主题
文本预览
相关文档 最新文档