基于C#实现(WinForm)P2P聊天小程序

发布于:2025-06-25 ⋅ 阅读:(22) ⋅ 点赞:(0)

计算机网络大作业-P2P聊天小程序

一、功能介绍

1.1 登录

用户凭用户名和密码登录系统,可以更换服务器 IP 和端口,以防网络不畅通,连接服务器有 3 秒的超时时延。

1.2 查询好友是否在线,添加好友/接受好友请求

用户可以通过好友学号添加好友,如果好友在线,发出好友请求,对方可以选择接受或拒绝好友请求。

1.3 与好友文字聊天

添加好友后,可双击好友名打开聊天窗口,与好友进行文字聊天。

1.4 文件传输

在聊天窗口,用户可以向好友发送文件,好友收到文件名和大小后决定是否接收。

1.5 多人文字聊天

用户可以选择多个用户发起群聊,成为群主。群聊窗口打开后,群成员们可以多人聊天

1.5.1 文件分发

在群聊窗口中,每个群成员都可以上传文件,群成员上传的文件信息展示在群文件列表中。每个群成员都可以在群文件列表中双击下载文件。

1.5.2 UDP 协议通信

完成了使用 UDP 协议的文字聊天功能,这个功能的实现是在一个单独的工程中,因为如果两个客户端使用不同的协议,则二者不能通信,所以一个工程中最好使用统一的通信协议。

1.6 设计模拟服务器

为了调试的方便,我设计了模拟服务器(助教在课程群里说这可以作为选做之一)。

模拟服务器能完成助教提供服务器的所以功能,同时在 UI 界面显示收到的消息。

二、通信设计

2.1 与服务器的通信

登录、查询好友状态等操作需要与服务器进行通信。由于这些操作一般不需要与其他操作同时进行(不需要并行),可以让用户等待服务器的回应,所以用简单的串行同步通信完成。

2.2 添加好友

每个客户端都需要设置一个好友请求的监听端口(异步监听与异步接收),当监听并收到到好友请求时,用户选择是否接收好友请求,根据用户的选择向对方的好友请求监听端口发送回应。

2.3 单人聊天

每个客户端都需要设置一个聊天请求的监听端口(异步监听与异步接收)。

在用户双击好友名时,会向对方的聊天请求监听端口发送聊天请求。当客户端聊天请求的监听端口接收到连接时,马上向对方发送自己另一个可用的端口号,并在这个端口号开启监听,对方便会向这个端口号发起连接。

双方在新的端口连接成功后,创建聊天窗口,并传入这个 TCP 连接,双方之后的通信(异步接收与发送)都在这个 TCP 连接内完成。

2.4 发起群聊

每个客户端都需要设置一个群聊请求的监听端口(异步监听与异步接收)。

当用户选择多个好友并点击“发起群聊”按钮时,会向所选的每个好友的群聊监听端口发送群聊请求。

当客户端群聊请求的监听端口接收到连接时,马上向对方发送自己另一个可用的端口号,并在这个端口号开启监听,群聊发起方便会向这个端口号发起连接。

2.5 群聊

在群聊过程中,为了保证群主的权限,以及避免冗余的传输,群主将承担消息中转站的作用。每个人的消息将发送给群主,群主再将这些消息发送给除发送人以外的每个群成员。文件的信息(包括文件名和文件大小)会像文字消息一样分发,但文件内容会存储在群主本地,当有用户请求文件时向其发送。

2.6 UDP 文字聊天

UDP 文字聊天中,有单独的接收线程,如果接收到一条消息,则向对方发送 ack n;如果接收到 ack k,则记录下来。

当发送消息 n 时,开启 5 秒的定时器 n,如果定时器 n 当时,还没有收到 ack n,则向用户提示并重新发送。

2.7 模拟服务器

模拟服务器的设计采用了经典的服务器监听设计,服务器在端口8000进行监听,当有客户端发送消息时开辟一个新的线程对其内容进行处理并回复。

三、通信协议

3.1 添加好友

在添加好友的端口,由于接收方有拒绝接收好友请求的功能,所以需要一个通信协议。双方消息类型有三类:添加好友请求、接受好友请求、拒绝好友请求。message 为消息内容。

消息类型

message

添加好友请求

‘_f’+ 对方用户名

接受好友请求

‘_y’+ 对方用户名

拒绝好友请求

‘_n’+ 对方用户名

3.2 单人聊天

单人聊天时,双方之间发送的消息可能有三类:文字消息、文件内容、文件名。

将一方收到的字节流设为 message,采用下面的通信协议:

消息类型

message[0]

message[1:end]

文字消息

1

文字(string)

文件内容

2

文件内容(bytes)

文件名

3

文件名(string)

3.3 群聊

群聊的情况比较复杂,群聊中分两种用户:群主与群成员。

群主从群成员处收到的消息有 5 种,设群主收到的字节流为 message,采用下面的通信协议:

消息类型

message[0]

message[1:end]

文字消息

0

文字(string)

文件内容

2

文件内容(bytes)

文件长度和文件名

3

文件长度(string)+”_”+ 文件名(string)

用户退出消息

4

“q”(string)

请求文件

5

文件长度(string)+”_”+ 文件名(string)

群主需要向群成员发送几种消息,包括聊天信息(某位成员发送的信息)、群成员名(群聊刚建立以及有成员退出群聊时,群主向每位成员发送全部成员名)、文件内容(当群成员向群主申请文件时,群主向该成员发送文件内容)、文件信息(当群里有其他成员上传文件时,群主向大家发送文件信息)、群组解散、没有找到文件(群主没有找到成员申请的文件)。

设群成员收到的字节流为 message,采用下面的通信协议:

消息类型

message[0]

message[1:end]

文字消息

0

作者名(string)+“_”+ 消息内容(string)

成员名

1

所有成员名(string)拼接,群主名在第一个。

文件内容

2

文件内容(bytes)

文件消息

3

文件长度(string)+“”+ 上传者名字(string) +””+ 文件名(string)

群组解散

4

“q”

没有找到文件

5

四、界面设计

本项目的界面包括客户端和模拟服务器两大部分,客户端包括登录界面、好友列表界面、聊天窗口和群聊窗口。

4.1 客户端

在登录界面、用户可输入用户名、密码、服务器 IP 和端口。这些都有默认值,用户只需进行修改。

在好友列表界面,用户可实现添加好友、发起聊天、发起群聊功能。用户添加的好友会显示在好友列表,用户双击好友名发起聊天。用户在好友列表单击选中若干好友,点“发起群聊”按钮发起群聊。

在聊天窗口,用户可输入并发送文字信息,也可以向对方发送文件。

在群聊窗口,用户可以输入文字信息和上传文件。用户上传的文件显示在群里所有人的文件列表内,每个人都可以双击某文件来下载。

4.2 模拟服务器

模拟服务器能完成助教提供服务器的所以功能,同时在 UI 界面显示收到的消息。

五、总结

这次大作业完成了相对比较完整的聊天软件的设计,体验了自己设计软件通信、软件界面的感受,属实不易。在完成大作业的过程中遇到不少问题,比如两个客户端通信的时序问题、双方握手的协议问题等。

软件的一个界面内可能需要完成多个任务、需要监听多个端口,这就要求设计者有一个清晰的思路和鲁棒的通信方式,否则很容易陷入混乱。比如两个客户端在好友列表界面发起聊天,如果直接将二者发起聊天的 socket 连接传入聊天窗口进行通信,会出现通信与监听混乱的问题。所以需要当二者第一次连接后,在新的端口重新进行连接。

总之,通过完成这次大作业,我对课本理论知识的理解得到了提高,动手能力和解决问题的能力得到锻炼。将理论知识应用到实际中,给我带来了很大的成就感。