千家信息网

C++中SOCKET多线程怎么实现聊天小程序

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍了C++中SOCKET多线程怎么实现聊天小程序的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++中SOCKET多线程怎么实现聊天小程序文章都会有所收获,
千家信息网最后更新 2026年11月02日C++中SOCKET多线程怎么实现聊天小程序

这篇文章主要介绍了C++中SOCKET多线程怎么实现聊天小程序的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++中SOCKET多线程怎么实现聊天小程序文章都会有所收获,下面我们一起来看看吧。

TCP/IP协议与SOCKET

什么是网络协议?

计算机网络中,各个实体之间的数据交换必须遵守事先约定好的规则,这些规则就称为协议。

网络协议的组成要素有:

1.语法,数据与控制信息的结构或格式
2.语义:需要发出何种控制信息,完成哪些动作以及做出何种响应
3.时序:事件实现顺序的详细说明

在一个网络协议中,通信的实体的相同层次的结构必须执行相同的协议,这是协议的对等性原则。

TCP/IP体系结构与SOCKET

关于TCP/IP体系结构的详细内容本文不做论述,如果你没有这方面的知识想要快速理解这个东西,可以把网络通信类比成两个人之间写信。你的信件就是通信过程中要传递的消息或者数据,而网络协议对你的"信件"进行了包装,比如给你贴了邮票、包了信封、投进了邮箱,然后你的"信件"就能通过邮局送到收信人那里。

SOCKET(套接字)是TCP/IP网络操作系统为网络程序开发提供的典型网络编程界面,进程通过SOCKET发送消息和接收消息。你可以把SOCKET看作一道"门",发送消息的进程从"门"把消息推出去;消息被推出之后利用下层的通信设施传递到接收进程所在的"门";然后接收进程再从"门"把消息拉进去。套接字SOCKET又分为数据报套接字和流式套接字,分别使用UDP协议和TCP协议。

SOCKET编程

我们尝试编写一个单播聊天室,这个聊天室可以让多个客户端与服务器端进行连接,而单播的意思是各个客户端只能与服务端进行单独通信,不同客户端之间无法通信。为了实现这个目标我们还需要用到多线程。整体实现思路如下图:

话不多说,上代码。

Server端

#include "stdafx.h"#include#include#include#pragma comment (lib, "ws2_32.lib")using namespace std;const int PORT = 8000;#define IP "127.0.0.1"#define MaxClient 10//最多能接受同时在线的客户端数量,可以随意修改#define MaxBufSize 1024int num =0;//客户端数量计数器#define _CRT_SECURE_NO_WARINGS//服务线程DWORD WINAPI SeverThread(LPVOID lpParameter){    //新建一个SOCKET用于通信 SOCKET *ClientSocket = (SOCKET*)lpParameter; int receByt = 0; char RecvBuf[MaxBufSize]; char SendBuf[MaxBufSize]; char exitBuf[5]; //开始接收 while (1) {  receByt = recv(*ClientSocket, RecvBuf, sizeof(RecvBuf), 0);  if (receByt > 0)  {      //当客户端发来的消息是"exit",就关闭连接   if (strlen(RecvBuf)==4)   {    for (int i = 0; i < 5; i++)    {     exitBuf[i] = RecvBuf[i];    }    int flag = strcmp(exitBuf, "exit");    if (flag==0)//接收到exit消息    {     cout << "client " << *ClientSocket << " exit!" << endl;     num--;     send(*ClientSocket, "Your server has been closed", sizeof(SendBuf), 0);     closesocket(*ClientSocket);     return 0;    }   }    cout << "receive message :" << RecvBuf << " from client:" << *ClientSocket << endl;     }  else  {      //下面说到的客户端关闭连接是指客户端掉线了   if (WSAGetLastError() == 10054)//检测到客户端关闭连接   {    cout << "client " << *ClientSocket << " exit!" << endl;    closesocket(*ClientSocket);    num--;    return 0;   }   else//接收失败显示错误信息   {    cout << "failed to receive,Error:" << WSAGetLastError() << endl;    break;   }     }  memset(RecvBuf, 0, 1024);  cout << "input your message to client:" << endl;  scanf_s("%s",SendBuf,MaxBufSize);  int k = 0;  k = send(*ClientSocket, SendBuf, sizeof(SendBuf), 0);  if (k < 0)  {   if (WSAGetLastError()==10054)//检测到客户端主动关闭连接   {    cout << "client " << *ClientSocket << " exit!" << endl;    closesocket(*ClientSocket);    num--;    return 0;   }   else//发送失败显示错误信息   cout << "failed to send, Error:" << WSAGetLastError()<

在这个服务器端,每有一个新的客户端请求建立连接,服务器都会新开一个线程为一个客户端提供服务,并在这个线程中新建立一个SOCKET用于与客户端进行通信,同时服务器也应该能够在不同阶段(接收或发送)检测客户端是否已经断开连接,以便及时释放资源。

Client端

#include "stdafx.h"#include#include#include#include#pragma comment(lib,"ws2_32.lib")using namespace std;const int PORT = 8000;#define MaxBufSize 1024#define _CRT_SECURE_NO_WARINGSint _tmain(int argc, _TCHAR* argv[]){ WSADATA wsd; WSAStartup(MAKEWORD(2, 2), &wsd); SOCKET SocketClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN ClientAddr; ClientAddr.sin_family = AF_INET; ClientAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); ClientAddr.sin_port = htons(PORT); int n = 0; n = connect(SocketClient, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr)); if (n == SOCKET_ERROR) {  cout << "failed to connect" << endl;  return -1; } cout << "success to connect to Server" << endl;  char info[1024];//数据输入缓冲区 char SendBuff[MaxBufSize];//发送数据缓冲区 char RecvBuff[MaxBufSize];//接收数据缓冲区 while (1) {  cout << "input your message:" << endl;  scanf_s("%s",&info,MaxBufSize);    if (info[0] == '\0')   break;  strcpy(SendBuff, info);  memset(info, 0, sizeof(info));  int k = 0;  k = send(SocketClient, SendBuff, sizeof(SendBuff), 0);  memset(SendBuff, 0, sizeof(SendBuff));  if (k < 0)  {   cout << WSAGetLastError() << endl;   cout << "failed to send" << endl;  }  int n = 0;  n = recv(SocketClient, RecvBuff, sizeof(RecvBuff), 0);  if (n>0)  {   cout << "receive message from Server:" << RecvBuff << endl;   memset(RecvBuff, 0, sizeof(RecvBuff));  } } closesocket(SocketClient); WSACleanup(); return 0;}

在本例中,客户端与服务器建立连接后,必须由客户端先发送消息才能开启对话。支持中英文聊天,一次最多发送1024个字节的数据。你要建立多个客户端的话只需要再新建几个工程然后把Client的代码复制进去运行即可。或者直接多复制几个编译生成的exe程序。

关于"C++中SOCKET多线程怎么实现聊天小程序"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"C++中SOCKET多线程怎么实现聊天小程序"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

客户 客户端 消息 线程 服务 数据 网络 通信 程序 服务器 C++ 信息 套接字 知识 结构 进程 之间 信件 内容 缓冲区 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网公司 科技公司 腾讯科技 互联网女皇 互联网女皇 腾讯科技 互联网 视角下的科技创新 顺玮阁互联网科技 成都狮子座互联网科技 互联网科技咨询 互联网金融科技委员会 互联网科技有限公司 翻译 科技赋能互联网健康 隆华科技工业互联网 互联网科技实习生岗位职责 乌苏新华互联网科技做什么的 互联网在线教育科技创业 山东子淼互联网科技有限公司 元气玛特互联网科技公司是外包吗 江苏互联网智能科技软件 昆明中奇联合互联网科技 河南商务圈互联网科技有限公司 互联网大会出现的黑科技 互联网与科技 互联网高科技 互联网科技名片 蓝思科技飞鸽互联网 重庆互联网医院沙龙医盟信息科技 浙南科技城互联网大厦建设工程 内蒙古九一互联网科技 互联网公司黑科技创始人 互联网科技公司营业执照怎么办理 互联网科技快速发展优美句子
0