在Windows程序开发中,网络编程通常离不开socket。它作为应用层与传输层之间的抽象接口,可视为应用程序与网络协议进行通信的编程桥梁,实现数据的发送与接收,是网络应用开发的重要基础。
1、 新建MFC项目,设置项目名称与存储路径。
2、 在项目配置向导中,选择基于对话框模式,并启用Windows套接字选项。
3、 设计一个服务器操作界面,包含四个静态文本标签,其中最后一个用于显示当前连接的用户数量;配置一个按钮,用于启动或停止服务器运行;设置两个编辑框,一个供用户输入服务端口,另一个设为只读,用于实时显示系统事件日志信息。
4、 调整各控件属性时,需将编辑框2的多行显示和垂直滚动属性设为开启,以便支持多行内容展示并自动添加滚动条功能。
5、 通过类向导为控件添加变量和事件处理函数,变量按上表设置,事件仅需按钮按下。双击按钮可自动生成函数框架,随后在函数中添加相应代码即可完成功能实现。
6、 在类视图中新建一个继承自CSocket的类CServerSocket,并通过类向导为其添加三个成员函数,用于实现特定功能。
7、 查看CServerSocket的类视图,需调整先前自动生成的三个函数。
8、 修改ServerSocket.h头文件,添加主对话框指针变量的定义。
9、 包含主对话框头文件,用于实现电话服务相关功能界面的声明与调用。
10、 别忘了包含CPhoneServerDlg类的声明,确保头文件正确引入并定义相关功能。
11、 {
12、 主对话框指针对象,用于指向CPhoneServerDlg类型的对话框实例。
13、 };
14、 修改ServerSocket.cpp文件,确保其中调用的函数均在主对话框类中已定义。
15、 {
16、 调用接收数据函数,将当前对象作为参数传递。
17、 }
18、 {
19、 移除已下线用户,调用对话框的删除客户端功能。
20、 }
21、 {
22、 将新连接的客户端添加到对话框中。
23、 }
24、 CServerSocket类代码已实现,下一步将编写主类的相关函数功能。
25、 修改PhoneServerDlg.h头文件内容
26、 包含服务器相关的头文件。
27、 声明类CServerSocket时,必须包含该类的头文件以确保正确编译和链接。
28、 声明函数与定义变量
29、 监听套接字,用于启动并运行服务器端程序,等待客户端连接请求。
30、 声明一个链表 m_clientList,用于存放客户端用户信息。
31、 布尔变量m_connect,用于标识服务器当前连接状态。
32、 添加客户端,处理并响应其请求。
33、 移除已断开连接的客户端,释放对应套接字资源,更新用户列表,确保服务端连接状态同步。
34、 接收来自指定服务器套接字的数据。
35、 更新事件日志,传入字符串参数以记录最新事件信息。
36、 字符转换处理
37、 向所有客户端发送指定的消息内容。
38、 手机控制PC的响应功能,用于处理来自移动端的控制指令,实现设备间的交互与操作响应。
39、 修改PhoneServerDlg.cpp以实现头文件中定义的函数功能。
40、 先编写打开服务器按钮的点击响应功能。
41、 {
42、 在此处添加控件通知处理的相关代码。
43、 {
44、 将对话框中ID为IDC_StartServer的控件文本设置为打开服务器。
45、 系统即将关闭服务器,请及时保存数据并退出。
46、 }
47、 设置对话框为主窗口,此句必不可少。
48、 创建服务器套接字,默认使用本机IP地址。
49、 {
50、 弹出消息框显示创建套接字失败!
51、 }
52、 {
53、 弹出提示框显示监听失败!,提示操作未成功。
54、 }
55、 将对话框中ID为IDC_StartServer的控件文本设置为关闭服务器。
56、 系统已启动并成功开启服务器连接服务。
57、 }
58、 该函数用于启动或停止服务器,通过调用Create函数创建服务器实例,并使用Listen函数监听客户端连接请求。端口号由用户在编辑框中输入,程序仅支持1024至65535范围内的可用端口,确保符合系统端口使用规范。
59、 编写AddClient函数以添加用户并响应其请求。
60、 {
61、 更新事件,提示用户已成功连接至服务器。
62、 }
63、 该函数在CServerSocket类的OnAccept消息处理中被调用,用于响应客户端连接请求。核心功能通过Accept函数实现,连接建立成功后,将新用户加入m_clientList链表中进行管理,同时更新系统日志,并向该用户发送Hello消息,以完成连接确认与欢迎提示,确保新连接被正确记录和响应。
64、 编写RemoveClient函数,实现移除已下线用户的功能。
65、 {
66、 {
67、 {
68、 用户已离开,触发更新事件。
69、 }
70、 }
71、 }
72、 该函数在CServerSocket类的OnClose事件中被触发,通过POSITION结构遍历用户链表,定位已下线的用户,将其资源释放,从链表中移除,并同步更新系统日志信息,确保连接状态的实时维护与记录完整。
73、 编写接收数据函数,实现数据获取功能。
74、 {
75、 {
76、 根据指令字符串控制计算机执行相应操作
77、 将数据发送给所有用户,包含原始发送者。
78、 }
79、 }
80、 该函数在CServerSocket类的OnReceive消息响应中被调用,负责对接收到的数据进行解析与处理,实现对计算机的远程控制。同时,将收到的数据转发给所有连接的客户端,实现类似群发消息的功能。通过CSocket类提供的GetPeerName方法,可获取当前连接用户的IP地址与端口号,用于标识和管理客户端连接。
81、 编写函数以更新事件日志信息,确保记录准确及时。
82、 {
83、 获取当前系统时间
84、 日志换行显示功能
85、 格式化当前时间显示
86、 获取编辑框末行的索引位置
87、 定位到编辑框的末尾行
88、 将选定行的内容替换为指定字符串。
89、 }
90、 该函数用于记录用户登录登出信息,遍布所有需更新日志的环节,便于服务器统一追踪操作事件。
91、 编写WChar2MByte函数,实现宽字符到多字节字符的转换功能。
92、 {
93、 }
94、 该函数在SendMSG中被调用,负责将宽字符转换为多字节字符集,若不进行此转换,接收端仅能接收到单字节数据,无法正确解析完整信息。
95、 编写SendMSG函数,实现向各客户端发送消息的功能。
96、 {
97、 {
98、 弹出消息框提示字符转换失败。
99、 }
100、 {
101、 }
102、 }
103、 发送函数用于向所有用户传递消息,核心功能由Send函数实现,可在AddClient和RecvData中调用,支持随时向用户发送信息。
104、 编写ControlPC函数,用于接收并解析指令,实现对电脑的远程控制,主要支持手机端操作。
105、 {
106、 当安卓控制参数为mop时,启动播放器功能。
107、 {
108、 }
109、 若安卓控制指令为mcl,则执行关闭媒体播放器操作。
110、 {
111、 第二个参数为进程ID,函数返回线程ID。
112、 }
113、 当 AndroidControl 的值为 mpl 或 mpa 时,执行播放或暂停操作。
114、 {
115、 }
116、 }
117、 控制功能可根据需求自行扩展,此处仅以音乐播放为例进行演示。通过ShellExecute函数调用外部应用程序实现功能启动;结束进程时较为复杂,需先获取目标程序窗口句柄,再通过OpenProcess获取进程句柄,最后调用TerminateProcess强制终止该进程,从而完成关闭操作。
118、 在类向导中添加虚函数PreTranslateMessage,并实现相应代码逻辑。
119、 {
120、 {
121、 }
122、 }
123、 此函数旨在禁用回车或退出键,避免程序意外终止。
124、 完成上述步骤后,服务器端程序即告完成。尽管函数较多,但只要掌握socket的使用流程,便可轻松理解,整体可归纳为四个步骤。
125、 搭建服务器环境
126、 客户端发起连接请求
127、 与客户端收发数据,实现信息交互。
128、 客户端与服务器连接中断
129、 通过添加辅助代码可优化网络通信效果,客户端具体实现方法将在后续内容中详细说明。
