1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 利用TCP和UDP协议 实现基于Socket的小聊天程序(初级版)

利用TCP和UDP协议 实现基于Socket的小聊天程序(初级版)

时间:2020-02-23 10:31:51

相关推荐

利用TCP和UDP协议 实现基于Socket的小聊天程序(初级版)

TCP

TCP (Transmission Control Protocol)属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,TCP支持的应用协议主要有:Telnet、FTP、SMTP等

TCP是面向对象的连接,是安全可靠的,是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,我 们这里只做简单、形象的介绍,你只要做到能够理解这个过程即可。我们来看看这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据, 可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候 发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发 送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

首先我们来看看用TCP实现聊天程序吧

实现聊天程序我们需要一个服务端一个客户端来模拟实现,我们首先来建立服务器端,直接贴代码,如下:

建立Socket并绑定IP和端口 1//首先建立一个套接字(服务器端)

2SocketsocketServer=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

3//将套接字绑定到本地的IP和端口

4IPEndPointendPoint=newIPEndPoint(IPAddress.Any,9999);

5//绑定套接字

6socketServer.Bind(endPoint);

7//输出语句服务已经启动

8Console.WriteLine("=====TCPServerIsOK======\r\n===IP:"+endPoint.Address+"Port:"+endPoint.Port+"===");

9//开始监听

10socketServer.Listen(10);

11//接受消息并返回的新的套接字对象

12Socketsk=socketServer.Accept();

简要介绍下个别变量,方法的作用:

socketServer:实例化一个服务端的Socket实例

endPoint:网络终结点,定义了IP和Port

Bind方法:用于将Socket实例绑定到该网络终结点上

Listen方法:监听端口,参数为监听序列的长度

Accept方法:接受通信,返回一个新的Socket对象,然后之后的通信就交由该新的对象来进行,socketServer就相当于公司的前台,只负责接待,具体的事务是通过它交由其他人来执行(个人理解)

然后是服务器端接受数据的代码,如下:

服务器端接受数据 1//接受数据

2

3//新建一个字节数组

4byte[]recveMsg=newbyte[1024*1024];

5//使用receive方法接受发送到服务器端的数据

6intbytes=sk.Receive(recveMsg,SocketFlags.None);

7//将数据进行编码

8stringreceive=System.Text.Encoding.UTF8.GetString(recveMsg,0,bytes);

9//将信息打印到控制台

10Console.WriteLine(receive);

简要解释下个别变量的作用:

recveMsg:这是一个字节数组,因为在接受数据时,我们需要将接收到的数据存放到字节数组中,所以我们要首先定义一个字节数组,这里我给了它1024*1024的大小

bytes:这是一个int型变量,作用就是用来接收Socket用Receive接受到数据的实际长度,但为什么我们需要这个变量呢,因为在后一行代码中,我们需要将字节数组转换为字符串来进行输出,如果没有这个变量来定义大小,我们每次都会把1024*1024的字节长度转换成字符串,所以往往有时候接收到的长度没有1024*1024大小,

因此会造成无用的转换。

然后就是发送数据,贴上代码:

服务器端发送数据 1//发送数据

2

3//实例化发送的信息

4stringmessage="HelloClinet,MyNameIsHolyKnight_Server";

5//将字符串转换成字节数组

6byte[]sendMsg=System.Text.Encoding.UTF8.GetBytes(message);

7//发送数据

8intsendBytes=sk.Send(sendMsg,SocketFlags.None);

9

10//关闭套接字

11socketServer.Close();

12

13Console.ReadKey();

简要的解释下个别变量的作用:

message:这个很显然,我们用message定义了一个字符串,来模拟要发送的数据

sendMsg:刚上面说了,接受数据时我们会用一个字节数组来接受,然后将数据存到该数组中,同理,发送也一样,发送的数据也要求是字节数组,所以我们同样定义一个字节数组来存放要发送的数据。

sendBytes:同样一个int型的变量,来接受Socket用Send发送数据的实际长度(大小)。

好,这样呢,我们的服务器端就搭建好了,这时我们需要一个客户端,所以下面我们来创建客户端

同样,首先也要新建一个Socket,并绑定IP和Port,再连接到远程主机,代码如下:

客户端Socket 1//新建一个套接字(客户端)

2SocketsocketClient=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

3//设置与远程主机连接的网络节点

4IPEndPointendPoint=newIPEndPoint(IPAddress.Parse("127.0.0.1"),9999);

5//与远程主机建立连接

6socketClient.Connect(endPoint);

简要解释下个别变量,方法的作用:

socketClient:实例化一个客户端的Socket对象

endPoint:网络终结点,这里用了127.0.0.1这个IP地址(回环地址),端口号必须和服务器端的相同

Connect方法:已经定义好了Socket对象和网络终结点了,这里就用Connect方法来实现和远程主机建立连接了

同样客户端也要进行发送和接受数据,由于两个方法和服务器端端的收发数据方法一致,这里就不再重复赘述了,直接贴上代码:

发送数据:

客户端发送数据 1//发送数据

2stringsendMsg="HelloServer,MyNameIsHolyKnight_Client";

3byte[]sendBytes=System.Text.Encoding.UTF8.GetBytes(sendMsg);

4intbytes=socketClient.Send(sendBytes,SocketFlags.None); 客户端接受数据 1//接受数据

2byte[]receiveMsg=newbyte[1024*1024];

3intreceiveBytes=socketClient.Receive(receiveMsg,SocketFlags.None);

4stringMessage=System.Text.Encoding.UTF8.GetString(receiveMsg,0,receiveBytes);

5Console.WriteLine(Message);

接受数据:

客户端接受数据 1//接受数据

2byte[]receiveMsg=newbyte[1024*1024];

3intreceiveBytes=socketClient.Receive(receiveMsg,SocketFlags.None);

4stringMessage=System.Text.Encoding.UTF8.GetString(receiveMsg,0,receiveBytes);

5Console.WriteLine(Message);

这样,我们的客户端也就搭建好了,所以至此,我们的小聊天程序的客户端和服务器端都搭建完毕,可以来运行看效果了,运行时,我们必须首先运行服务器端,然后再开启客户端进行远程连接,首先开启服务器端:显示【TCP Server Is OK】并显示了IP和Port,表示服务器端服务已成功开启,图如下:

接下来运行客户端程序,客户端已开启就会连上服务器端,并接受到服务器发送过来的数据,运行效果如图:

此时,服务器端也应该接受到了来自客户端的数据,查看,果然收到了数据,如图:

至此,一个基于TCP的Socket的简单通信就完成了,,,,下面我们要开看看,用UDP同样来实现这个效果。。。

UDP

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是 一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,与TCP不同的是,UDP是面向无连接的,它没有TCP传输前的“三次握手”的机制,是一种不可靠的传输机制。。

我们再来看看用UDP实现小聊天程序吧,,,

同TCP一样,UDP同样需要一个服务器端和一个客户端来模拟对话,我们就用两个控制台应用程序实现,首先我们来搭建服务器端,贴上代码:

UDP服务器端Socket //第一步定义一个Socket

SocketsocketServer=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

//第二步设置一个网络节点

IPEndPointendPoint=newIPEndPoint(IPAddress.Any,8888);

//将socketServer绑定到网络节点上

socketServer.Bind(endPoint);

//【Tcp的时候需要监听但DUP不需要监听】

//socketServer.Listen(10);

//输出一句话提示服务已开启

Console.WriteLine("===UDPServerIsOK===\r\nIP:"+endPoint.Address+"Port:"+endPoint.Port);

【解释】:与TCP一样,实例化一个Socket对象,然后新建一个网络终结点,并指定IP和Port,然后将Socket对象绑定到该终结点上

【不同】:由于UDP是面向无连接的,所以在UDP中并不需要监听机制

大家还记得上面TCP接受到通信时是怎样处理的么??是的,Accept方法返回了一个新的Socket对象,之后由该对象进行通信,那UDP呢?先看代码吧。。

新网络地址 1//定义要发送的计算机的地址端口为0的时候表示系统分配端口

2IPEndPointsender=newIPEndPoint(IPAddress.Any,0);

3//建立一个网络地址

4EndPointRemote=(EndPoint)sender;

原来在UDP中,我们首先会实例化一个新的网络地址(该地址的IP为任意IP,端口号为0,表示由系统分配端口),在收发数据时,将该网络地址引用到主机的网络地址上,之后我们就可以通过这个网络地址来收发数据了

接下来开始收发数据,首先接受数据的代码:

UDP接受数据 1//第三步通过套接字收发报文

2byte[]data=newbyte[1024*1024];

3//接受数据报文到缓冲区并存储终结点

4intreceive=socketServer.ReceiveFrom(data,refRemote);

5//打印到控制台

6Console.WriteLine("MessageReceivedFrom{0}",Remote.ToString());

7Console.WriteLine(System.Text.Encoding.UTF8.GetString(data,0,receive));

【解释】:同样,我们在接受数据的时候要将数据存放到一个字节数组中,所以我们仍然会定义一个字节数组data

【不同】:1).我们除了存放接收到的数据,我们还要将远程主机的通信节点信息存储下来,注意参数类型ref ,为引用类型,也就是将该类型用指针指向了主机节点类型的地址。

2).接受数据的方法,TCP中为Receive方法,UDP中为ReceiveFrom方法

接下来看看发送数据的代码,如下:

UDP发送数据 1//要发送的数据

2stringsendMsg="HelloClient,MyNameisHolyKnight_UdpServer";

3//将数据转换成字节数组

4data=System.Text.Encoding.UTF8.GetBytes(sendMsg);

5//将数据发送到指定的网络地址

6socketServer.SendTo(data,SocketFlags.None,Remote);

【解释】:我们发送数据时,定义了一个字符串作为模拟发送数据,当然,它发送数据也是要求为字节数组,同样的我们做了转换

【不同】:1).在TCP中我们发送数据,直接将字节数组作为参数发送就可以了,但在UDP中,我们多了一个参数,就是我们之前指定的新的终结点,由于在前面的接收数据代码中,我们已经用

该参数保存了远程主机通信节点的信息了,所以我们在这里发送数据的时候,直接将数据发送到该网络节点就可以了

2).TCP中的发送方法为Send,而在UDP中为SendTo。

同时我们还实现循环收发数据,思路很简单,就是把收发数据放在了一个死循环中,代码如下:

循环收发数据 1intcount=0;

2try

3{

4//循环收发数据

5while(true)

6{

7//接受数据

8data=newbyte[1024*1024];

9//从端点接受数据

10receive=socketServer.ReceiveFrom(data,refRemote);

11//打印到控制台

12Console.WriteLine("TheClientSay:"+System.Text.Encoding.UTF8.GetString(data,0,receive));

13count++;

14

15//发送数据

16stringreply="这是服务器的第"+count.ToString()+"次回复";

17//数据转换

18data=System.Text.Encoding.UTF8.GetBytes(reply);

19//发送数据到指定端点

20socketServer.SendTo(data,Remote);

21}

22}

23finally

24{

25//关闭套接字

26socketServer.Close();

27}

好,,这样我们UDP的服务器端也搭建完成了,,接下来同理,搭建客户端。。

实现原理和服务器端一样,所以就不解释了,直接上代码吧:

UDP客户端 1//第一步建立一个Socket

2SocketsocketClient=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

3

4//第二步通过套接字收发报文

5Console.WriteLine("按任意键开始向服务器发送数据");

6Console.ReadKey();

7

8byte[]data=newbyte[1024*1024];

9stringinput,stringData;

10

11IPEndPointendPoint=newIPEndPoint(IPAddress.Parse("127.0.0.1"),8888);

12data=Encoding.UTF8.GetBytes("HelloServer,MyNameIsHolyKnight_UdpClient");

13

14//将数据发送到服务器的终结点

15socketClient.SendTo(data,endPoint);

16

17//定义一个发送终结点,没有具体的IP和Port

18IPEndPointsender=newIPEndPoint(IPAddress.Any,0);

19

20//定义一个网络地址

21EndPointRemote=(EndPoint)sender;

22

23//重新实例化一个字节数组用于存放接受到的数据

24data=newbyte[1024*1024];

25//接受数据将数据保存到data数据将远程主机的节点保存到Remote终端中【注意ref引用】

26intreceive=socketClient.ReceiveFrom(data,refRemote);

27

28Console.WriteLine("MessageReceiveFrom{0}",Remote.ToString());

29Console.WriteLine(Encoding.UTF8.GetString(data,0,receive));

30

31//循环收发数据

32while(true)

33{

34//从键盘读取数据

35input=Console.ReadLine();

36if(input=="exit")

37{

38break;

39}

40//同样的发送数据到Remote节点

41socketClient.SendTo(Encoding.UTF8.GetBytes(input),Remote);

42data=newbyte[1024*1024];

43

44//同样的接受数据并再次更新存储终结点

45receive=socketClient.ReceiveFrom(data,refRemote);

46stringData=Encoding.UTF8.GetString(data,0,receive);

47

48Console.WriteLine("服务器说:"+stringData);

49}

50

51//关闭套接字

52Console.WriteLine("StoppingClient");

53socketClient.Close();

54Console.ReadKey();

55}

好了,,这样服务器端和客户端都搭建完毕,接下来就是看看运行效果了,直接上图

首先开启服务器端:

我们看到【UDP Server Is Ok】和IP,Port,证明此时UDP服务器端已成功开启了,,,

接下来开启客户端:

客户端开启成功,提示按任意键开始发送数据。。

接下来我们在客户端连续给服务器发送三条消息

客户端:

服务器端:

接下来我们在客户端输入“exit”请求停止通信,效果:

输入"exit“ 之后,客户端就提示 "Stopping Client”,这样就停止通信了,,,

哈哈,,就这样,通过TCP和UDP实现通信聊天程序就完成了,,当然这个是最基础的通信例子,,在下一篇博客中将用窗体程序和多线程来实现聊天程序,尽请关注,,,,

这里附上小Demo的源代码:

/Files/holyknight-zld/SocketDemo/SocketDemo.rar

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。