栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++跨平台开发——关于解决SOCKET网络编程中客户端对聊的问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++跨平台开发——关于解决SOCKET网络编程中客户端对聊的问题

一、多进程实现

        前面我们在SOCKET网络编程学习中,简单实现了服务器为客户端单独开一个进程,客户端网络连接成功之后可以输入数据,并陆续给服务器发送消息,服务器只实现读取操作。

基于VS2019 C++的跨平台(Linux)开发(2.2)——SOCKET网络编程

        因为之前服务器中没有实现write,所以只能实现客户端发消息给服务器。那么如果想要让客户端和客户端进行聊天该怎么办?

        服务器作为中转站,要实现客户对聊,就要把服务器保存的消息再发送给另一方的客户端。(如下图)利用write写出去,并且writefd是5

        但是此时会出现这样的问题:每一个客户端是一个进程,比如客户端A有一个acceptfd为4,当客户端B上线之后,才有第二个acceptfd为5,会把上一次的acceptfd覆盖(因为声明的acceptfd变量就一个)。

        因为开的是进程,即此时acceptfd=4的进程要给acceptfd=5的进程发消息(acceptfd=5的进程要给acceptfd=4的进程发消息),但是拿不到两个进程都获取不到对方的acceptfd ,因为进程之前数据不能共享。(不能定义全局变量进行加减操作获取acceptfd,就算可以,也不能保证另一个客户端acceptfd=5,就像你登录QQ的时候,腾讯公司不会告诉你是今天第几个上线的用户,但是登录QQ要使用唯一的QQ号,服务器只能通过QQ号识别客户端)

        所以,通过id号和acceptfd就可以一一对应了,就像map中的键值对,这时候大家可能会想到定义一个全局map容器把两者存起来,但是依然逃不掉进程间不能共享全局变量问题,所以很遗憾还是解决不了问题。

        综上,使用进程代表一个客户端本身就是不对的,用了进程就不得不用IPC,这样都会变得更加复杂。所以就得使用多线程技术。


二、多线程实现 

        所以,客户端上线之后服务器要调用pthread_create创建线程为他服务,然后要去处理acceptfd的读写操作。思路如下

        首先,要使用map将用户ID和acceptfd绑定。因为客户端上线只有acceptfd,还不知道用户的ID,实现不了将acceptfd和账号进行绑定。所以要在线程的处理函数进行死循环,再用read读取acceptfd,并查询数据库获取账号密码,判断账号密码是否正确,只有验证登录成功后才用map保存下来并插入数据库。(即map保存要在read后操作)。所以在pthread_create的时候要传入acceptfd。

        其次,read后要write(acceptfd)。那么只有明确了“我是谁、跟谁聊、聊什么”才能告诉服务器要跟谁聊天,这时就可以定义一个结构体(如下图)—— 根据业务自定义通信协议。然后根据接收者账号(recvID),在map容器查询对应的acceptfd,然后即可以write(acceptfd)了。

 注意:

1、调用线程处理函数没必要传map,本来就可以支持全局变量的使用,可以直接访问。

2、不能将acceptfd定义为全局变量,因为服务器调用accept后返回acceptfd会一直把全局的acceptfd覆盖,导致所有的线程只为最后一次上线的客户端服务


三、案例

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/784059.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号