C++基于socket的单线程服务器客户端聊天程序(TCP)

2023-05-16

编写服务器端的基本步骤:

  1. 初始化winsock;
  2. 创建socket;
  3. 绑定socket;
  4. 在socket上对客户端进行监听;
  5. 接受客户端的连接;
  6. 收发消息;
  7. 断开连接;
话不多说,直接上码

//服务器端
#include <iostream>
#include "winsock2.h"
#include "string.h"
using namespace std;

#pragma comment(lib,"ws2_32.lib")

int main()
{
    //初始化socket
    WSADATA wsaData;//改结构体包含winsock实现的信息
    if (WSAStartup(MAKEWORD(2, 2), &wsaData)  !=  0)
    {
        cout<<"WSAStratup error!"<<endl;
        exit(1);
    }
    //建立socket
    SOCKET servers = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(servers == INVALID_SOCKET)
    {
        cout<<"Failde to create server socet!Error code:"<<WSAGetLastError()<<endl;
        WSACleanup();
        exit(1);
    }
    //绑定socket
    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(8888);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    if (bind(servers, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        cout<<"Failed to bind server socket!Error code:"<<WSAGetLastError()<<endl;
        WSACleanup();
        exit(1);
    }
    //监听socket
    if (listen(servers, 10) == SOCKET_ERROR)//消息等待队列为10
    {
        cout<<"Failed to listen server socket!Error code:"<<WSAGetLastError()<<endl;
        WSACleanup();
        exit(1);
    }
    cout<<"Server started successfully..."<<endl;
    //接收客户端请求
    SOCKET sclient;
    SOCKADDR_IN clientAdd;
    int cAddlen = sizeof(clientAdd);
    char buf[255];//缓冲区  大小为255
    char sendbuf[255];//发送缓冲区
    sclient = accept(servers, (LPSOCKADDR)&clientAdd, &cAddlen);
    if (sclient == SOCKET_ERROR)
    {
        cout<<"Failde to accept client!Error code:"<<WSAGetLastError()<<endl;
        WSACleanup();
        exit(1);
    }
    printf("接收到一个连接:%s\n", inet_ntoa(clientAdd.sin_addr));
    //接收和发送数据
    while (true)
    {
        memset(buf,0,sizeof(buf));
        memset(sendbuf,0,sizeof(sendbuf));
        int res = recv(sclient, buf, sizeof(buf), 0);
        if (res > 0)
        {
            cout<<"client:"<<buf<<endl;
        }
        else if(res == 0)
        {
            cout<<"Connect close..."<<endl;
            break;
        }
        else
        {
            cout<<"Failed to receive message from client!Error code:"<<WSAGetLastError()<<endl;
            closesocket(sclient);
            return 0;
        }
        cout<<"server:";
        gets(sendbuf);
        if (strcmp(sendbuf, "bye") == 0)
        {
            cout<<"Client requests to close the connection..."<<endl;
            break;
        }
        res = send(sclient, sendbuf, strlen(sendbuf), 0);
        if(res == SOCKET_ERROR)
        {
            cout<<"Failed to send message to client!Error code:"<<WSAGetLastError()<<endl;
            closesocket(sclient);
            return 0;
        }
    }
    //关闭socket连接
    closesocket(sclient);
    closesocket(servers);
    cout<<"socket close..."<<endl;
    WSACleanup();
    return 0;
}



编写客户端的基本步骤:

  1. 初始化winsock;
  2. 创建socket;
  3. 连接服务器;
  4. 收发消息;
  5. 断开连接;
//客户端
#include <iostream>
#include "winsock2.h"
#include "string.h"
using namespace std;

#pragma comment(lib,"ws2_32.lib")

int main()
{
	//初始化winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
	{
		cout<<"WSAStratup error!"<<endl;
		exit(1);
	}
	//创建socket
	SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if(client == INVALID_SOCKET)
	{
		cout<<"Failde to create client socet!Error code:"<<WSAGetLastError()<<endl;
		WSACleanup();
		exit(1);
	}
	//连接服务器
	SOCKADDR_IN sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8888);//服务器端口
	sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//服务器IP
	if (connect(client, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		cout<<"Failde to connect with server!Error code:"<<WSAGetLastError()<<endl;
		WSACleanup();
		exit(1);
	}
	char sendbuf[255];
	char recbuf[255];
	//收发消息
	while (true)
	{
		memset(sendbuf,0,sizeof(sendbuf));
		memset(recbuf,0,sizeof(recbuf));
		cout<<"client:";
		gets(sendbuf);
		int res = send(client, sendbuf, strlen(sendbuf),0);
		if (strcmp(sendbuf, "bye") == 0)
			break;
		if(res == SOCKET_ERROR)
		{
			cout<<"Failed to send message!Error code: "<<WSAGetLastError()<<endl;
            closesocket(client);
            WSACleanup();
            exit(1);
		}
		res = recv(client, recbuf, 255,0);
		if (res > 0)
		{
			cout<<"server:"<<recbuf<<endl;
		}
		else
		{
			cout<<"Failed to receive message from server!Error code:"<<WSAGetLastError()<<endl;
			closesocket(client);
			return 0;
		}
	}
	//关闭socket
	closesocket(client);
	WSACleanup();
	cout<<"socket close..."<<endl;
        return 0;
}
第一次写,有不对的地方,还求大佬们指正,不喜勿喷。














本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++基于socket的单线程服务器客户端聊天程序(TCP) 的相关文章

  • 信息学奥赛一本通C++语言-----2028:【例4.14】百钱买百鸡

    题目描述 百钱买百鸡问题 鸡翁一 xff0c 值钱五 xff0c 鸡母一 xff0c 值钱三 xff0c 鸡雏三 xff0c 值钱一 xff0c 百钱买百鸡 xff0c 问鸡翁 鸡母 鸡雏各几何 xff1f 输入 无 输出 输出各种鸡翁 鸡
  • therecipe/qt 安装实录

    therecipe qt 是github com上的golang 43 qt5项目 xff0c 主要是针对golang没有GUI而生的 xff0c qt5和golang一样具有跨平台及对C 43 43 原生支持 费话不多说了 xff0c 下
  • Code blocks 编译Fortran(转载)

    方法一 xff1a 下载页面 xff1a http www codeblocks org downloads binaries 下载 codeblocks 17 12mingw fortran setup exe 这样的版本 方法二 xff
  • Python编程基础:第三十八节 问答游戏Quiz Game

    第三十八节 问答游戏Quiz Game 前言实践 前言 我们这一节还是对之前学习内容的一个综合运用 xff0c 主要涉及到函数编程 字典以及列表的使用 条件语句 循环结构等等 通过本节的学习读者可以检验之前内容的掌握情况 我们以问答游戏为例
  • 如何用ajax从前端传一个数组到后端处理,前端使用js,后端为nodejs(源码)

    在给后端传输数据时 xff0c 经常使用的是对象 xff0c 但是如果需要传一个数组时就需要无法采用常规方法 1 想传一个数组到后端时 xff0c 无法使用URL路径传参 xff0c 所以本方法采取正文传参 xff1a 前端js let a
  • Qt QFileSystemModel详解

    1 QFileSystemModel简介 QFileSystemModel 提供了一个可用于访问本机文件系统的数据模型 QFileSystemModel 和视图组件 QTreeView 结合使用 xff0c 可以用目录树的形式显示本机上的文
  • Qt QMenu简介

    1 常用方法 添加带图标 xff0c 文字的菜单项 QAction addAction const QIcon amp icon const QString amp text 添加带快捷键 xff0c 带菜单项接收槽 QAction add
  • 成功解决Error running ‘Application‘: command line is too long

    解决方法 xff08 推荐 xff09 xff1a idea点击 Run gt Edit Configurations 下拉选择JAR manifest 开始是没有这个选项的 xff0c 点击Modify options 点击shorten
  • MySQL密码忘记了如何操作

    目录 MySQL密码忘记了如何操作 连接MySQL时出现 xff1a ERROR 1045 28000 Access denied for user root 64 localhost using password YES 时 xff0c
  • Linux内核实现ns级别定时器及应用层实现us级高精度定时

    内核态ns us定时器 内核态常规实现精准定时器再linux2 6版本提出hrtime模块能达到ns级别精准定时 实现方法如下 xff08 内核hrtime为我们提供了创建与运行接口 xff09 xff1a include lt linux
  • 链表逆序操作C++版本

    链表逆序操作 xff1a 步骤如下 xff1a 首先先记住当前节点的下一个节点的位置 xff0c 因为如果将该节点插入至新节点 xff0c 需要改变它的next指向然后 xff0c 将当前节点的next指向newhead指向的节点最后 xf
  • JS模块化——02——common.js

    浏览器有时候识别es5的语法 xff0c 而我们写代码时写的是es6语法 xff0c 所以要打包 这样能转换成es5的代码 1 commonjs基于服务端 node 应用 结合引入第三方模块小案例 package json中name是包名
  • POJ 3259 Wormholes(负权环路)

    题意 xff1a 农夫约翰农场里发现了很多虫洞 xff0c 他是个超级冒险迷 xff0c 想利用虫洞回到过去 xff0c 看再回来的时候能不能看到没有离开之前的自己 xff0c 农场里有N块地 xff0c M条路连接着两块地 xff0c W
  • PaddleOCR 文字检测/文字块检测的模型训练过程,DBnet的前处理和后处理流程损失函数

    文章目录 1 环境搭建2 数据集3 下载预训练模型4 配置文件DecodeImageDetLabelEncodeIaaAugmentEastRandomCropDataMakeBorderMap 5 开启训练6 纯记录 xff0c 我在我服
  • 手机的散热背夹的物理原理

    可能使用了以下一些技术原理 xff1a xff08 1 xff09 利用导热材料 xff1a 通过在散热背夹中采用高导热率的材料 xff0c 如铜或铝等 xff0c 将手机产生的热量快速传递到散热背夹中 xff0c 从而降低手机温度 xff
  • 【算法题目】【Python】彻底刷遍DFS与回溯的算法题目

    文章目录 参考资料热身 xff1a 树的前序 中序 后序遍历热身 xff1a 树的层次遍历纯DFS与回溯法的区别纯DFS与回溯法的算法题目组合组合总和 III电话号码的字母组合组合总和组合总和 II分割回文串复原 IP 地址子集子集 II递
  • 【算法题目】使用Python生成一个数独游戏的棋盘

    难度可以控制 xff0c 且解法唯一 xff0c 时间复杂度看运气 首先 xff0c 我们定义了一个 SudokuGenerator 类 然后 xff0c 我们定义了 generate 方法来生成数独游戏 该方法生成了一个 9 9 的矩阵
  • 【算法题目】【Python】一文刷遍贪心算法题目

    文章目录 介绍分配饼干K 次取反后最大化的数组和柠檬水找零摆动序列单调递增的数字买卖股票的最佳时机 II买卖股票的最佳时机含手续费分发糖果根据身高重建队列跳跃游戏跳跃游戏 II用最少数量的箭引爆气球无重叠区间划分字母区间 介绍 贪心算法是一
  • following signatures couldn‘t be verified because the public key is not available: NO_PUBKEY

    the following signatures couldn t be verified because the public key is not available NO PUBKEY 3B4FE6ACC0B21F32 This er
  • 【运维】Linux中的常用的一些文件和作用

    bin xff1a 包含系统启动和基本维护所需的二进制可执行文件 boot xff1a 包含用于系统引导的文件 xff0c 包括内核文件和引导加载程序 dev xff1a 包含与设备相关的文件 xff0c 如硬盘驱动器 键盘等 etc xf

随机推荐