900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

时间:2021-12-14 11:01:36

相关推荐

Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)

前言

感觉Winsock网络编程的api其实和Linux下网络编程的api非常像,其实和其他编程语言的网络编程都差不太多。博主用Qt实现的,当然不想用黑窗口呗,有界面可以看到,由于GUI编程的话 一般UI进程不能阻塞,肯定需要多线来实现,在等待用户连接的时候accept,和客户端通信 等待消息的时候recv这些都是阻塞的 都需要在后台进程中。博主使用的是Qt5.9.7

界面效果

先看下效果再说

Winsock面向连接的接口

Winsock初始化和释放

WSAStartup、WSACleanup

服务端:

socket() -> bind() -> listen() -> accept() -> send() / recv() -> closesocket()

客户端:

socket() -> connect() -> send() / recv() -> closesocket()

这些函数都在msdn上有,这里就不过多的阐述

代码展示

服务端 将与客户度建立连接的 过程放到单独的线程中进行处理了,这个线程 做的事就是等待客户端连接,客户端连接后 单独再开一个线程专门与客户度进行通信,这样就不会导致界面无响应了。这里线程和线程间的通信是使用的Qt中的信号槽机制。

处理客户端连接请求代码

void SocketThread::run(){sockaddr_in clientAddr;int size = sizeof(clientAddr);while(!isInterruptionRequested()){//每次接受新客户端将之前的地址信息清0memset(&clientAddr,0,sizeof(clientAddr));//等待新客户端连接 阻塞函数,结束线程 使用requestInterruption打断线程并没有用,只能使用terminate 终止线程SOCKET client = ::accept(mListen,(sockaddr*)&clientAddr,&size);char* clientIp = inet_ntoa(clientAddr.sin_addr);int clientPort = ntohs(clientAddr.sin_port);QTime time = QTime::currentTime();QString str = time.toString("hh:mm:ss");QString msg = QString("%1 [%2:%3] connect success").arg(str).arg(clientIp).arg(clientPort);//新客户端连接,通知 UI 更新界面emit isMsg(msg);//开启新线程和客户端进行通信MsgThread* msgThread = new MsgThread(client,clientAddr,parent);msgThread->start();connect(msgThread,&MsgThread::isMsg,this,[=](QString msg){//转发消息给 UI进程,UI进行界面更新emit isMsg(msg);});connect(this,&SocketThread::isClose,this,[=](){msgThread->terminate();msgThread->quit();delete msgThread;});}}

服务端和客户端通信的代码

void MsgThread::run(){//inet_addr点分十进制转网络ip地址 ,inet_ntoa网络转点分十进制char* clientIp = inet_ntoa(mAddr.sin_addr);int clientPort = ntohs(mAddr.sin_port);while(true){memset(resp,0,1024);char buf[1024] = {0};//阻塞等待 接受信息int ret = recv(mClient,buf,1024,0);QTime time = QTime::currentTime();QString str = time.toString("hh:mm:ss");if(ret == 0){//连接断开emit isMsg(QString("%1 [%2:%3] is closed!!!").arg(str).arg(clientIp).arg(clientPort));break;}QString msg = QString("%1 [%2:%3]:%4").arg(str).arg(clientIp).arg(clientPort).arg(buf);//接受到消息,通知UI 界面更新emit isMsg(msg);//给用户进行响应消息,小写变大写strcpy(resp,QString(buf).toUpper().toUtf8().data());qDebug() << "给客户端发送消息:" << resp;send(mClient,resp,strlen(resp)+1,0);}}

完整代码

完整项目代码可以点这里进行下载,或者github下载最新代码。

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