Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)
生活随笔
收集整理的這篇文章主要介紹了
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下載最新代碼。
總結
以上是生活随笔為你收集整理的Qt:Qt实现Winsock网络编程—TCP服务端和客户端通信(多线程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (十一)模仿学习
- 下一篇: 4. OD-去除烦人的nag窗口(去除提