windows C/C++ socket 一对多(select)

2024年C/C++实现SMTP/POP3邮件客户端:从Socket到MIME的完整指南 网络编程是构建分布式系统的核心技术,其基础在于理解应用层协议的工作原理。SMTP和POP3作为经典的邮件传输协议,采用基于TCP的“命令-响应”模式,通过状态机管理会话流程,体现了应用层协议设计的通用范式。掌握这些协议不仅能深化对网络分层的理解,更能提升处理数据编码、加密通信和错误恢复的工程能力。在C/C++中直接基于Socket实现协议交互,尤其涉及OpenSSL集成与MIME解析时,开发者必须直面内存管理、缓冲区安全和字符串处理等系统级挑战。这种实践对于构建高性能服务、嵌入式通信模块或准备底层开发面试极 阅读详情

承接上一篇:https://blog.youkuaiyun.com/uVarAndMethod/article/details/90386058 

////server端
#include <stdio.h>  
#include <string.h>  
#include <WINSOCK2.H>  
  
#pragma comment(lib,"ws2_32.lib")  
  
#define INT_SERVER_PORT 5000  
#define STR_SERVER_IP "127.0.0.1"  
#define INT_DATABUFFER_SIZE 100  
  
void main(void)  
{  
    WORD dwVersion = MAKEWORD(2,2);  
    WSAData wsaData;  
    WSAStartup(WINSOCK_VERSION,&wsaData);  
  
    SOCKET sockServer = socket(AF_INET,SOCK_STREAM,0);  
    if (INVALID_SOCKET == sockServer)  
    {  
        printf("Failed to create socket!\n");  
        WSACleanup();  
        return;  
    }  
  
    sockaddr_in addrServer;  
    memset(&addrServer,0,sizeof(sockaddr_in));  
    addrServer.sin_family = AF_INET;  
    addrServer.sin_port = htons(INT_SERVER_PORT);  
    addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
    //addrServer.sin_addr.s_addr = htonl(INADDR_ANY);  
  
    int iResult;  
  
    bool bReuseAddr=true;  
    iResult=setsockopt(sockServer,SOL_SOCKET,SO_REUSEADDR,(char *)&bReuseAddr,sizeof(bReuseAddr));  
    if(SOCKET_ERROR == iResult)  
    {  
        printf("Failed to set resueaddr socket!\n");  
        WSACleanup();  
        return;  
    }  
      
    /* 
    unsigned   long cmd = 1;  
    iResult= ioctlsocket(sockServer,FIONBIO,&cmd); */  
  
    iResult = bind(sockServer,(sockaddr *)&addrServer,sizeof(addrServer));  
    if (SOCKET_ERROR == iResult)  
    {  
        printf("Failed to bind address!\n");  
        WSACleanup();  
        return;  
    }  
  
    if (0 != listen(sockServer,5))  
    {  
        printf("Failed to listen client!\n");  
        WSACleanup();  
        return;  
    }  
  
    UINT i = 0;  
    SOCKET sockAccept;  
    sockaddr_in addrAccept;  
    int iAcceptLen = sizeof(addrAccept);  
    char szDataBuff[INT_DATABUFFER_SIZE];  
    int iRecvSize;  
      
    sockaddr_in addrTemp;  
    int iTempLen;  
  
    fd_set fd;  
    FD_ZERO(&fd);  
    FD_SET(sockServer,&fd);  
  
    /* 
    timeval tm; 
    tm.tv_sec = 0; 
    tm.tv_usec = 1000; 
    */  
    printf("Start server...\n");  
    while(1)  
    {  
        fd_set fdOld = fd;  
        iResult = select(0,&fdOld,NULL,NULL,/*&tm*/NULL);  
        if (0 <= iResult)  
        {  
            for(i = 0;i < fd.fd_count; i++)  
            {  
                if (FD_ISSET(fd.fd_array[i],&fdOld))  
                {  
                    //如果socket是服务器,则接收连接  
                    if (fd.fd_array[i] == sockServer)  
                    {  
                        memset(&addrAccept,0,sizeof(addrTemp));  
                        sockAccept = accept(sockServer,(sockaddr *)&addrAccept,&iAcceptLen);  
                        if (INVALID_SOCKET != sockAccept)  
                        {  
                            FD_SET(sockAccept,&fd);  
                            //FD_SET(sockAccept,&fdOld);  
                            printf("%s:%d has connected server!\n",inet_ntoa(addrAccept.sin_addr),  
                                ntohs(addrAccept.sin_port));  
                        }  
                    }  
                    else //非服务器,接收数据(因为fd是读数据集)  
                    {  
                        memset(szDataBuff,0,INT_DATABUFFER_SIZE);  
                        iRecvSize = recv(fd.fd_array[i],szDataBuff,INT_DATABUFFER_SIZE,0);  
                        memset(&addrTemp,0,sizeof(addrTemp));  
                        iTempLen = sizeof(addrTemp);  
                        getpeername(fd.fd_array[i],(sockaddr *)&addrTemp,&iTempLen);  
                          
                        if (SOCKET_ERROR == iRecvSize)  
                        {  
                            closesocket(fd.fd_array[i]);  
                            FD_CLR(fd.fd_array[i],&fd);  
                            i--;  
                            printf("Failed to recv data ,%s:%d errorcode:%d.\n",  
                                inet_ntoa(addrTemp.sin_addr),ntohs(addrTemp.sin_port),WSAGetLastError());  
                            continue;  
                        }  
  
                        if (0 == iRecvSize)  
                        {  
                            //客户socket关闭  
                            printf("%s:%d has closed!\n",inet_ntoa(addrTemp.sin_addr),  
                                ntohs(addrTemp.sin_port));  
                              
                            closesocket(fd.fd_array[i]);  
                            FD_CLR(fd.fd_array[i],&fd);  
                            i--;      
                        }  
                          
                        if (0 < iRecvSize)  
                        {  
                            //打印接收的数据  
                            printf("recv %s:%d data:%s\n",inet_ntoa(addrTemp.sin_addr),  
                                ntohs(addrTemp.sin_port),szDataBuff);  
                        }  
                    }     
                }  
            }  
        }  
        else if (SOCKET_ERROR == iResult)  
        {  
            //WSACleanup();   
        //  printf("Faild to select sockt in server!\n");  
            Sleep(100);  
        }  
    }  
    WSACleanup();  
}  

   客户端的话上一篇中的tcp客户端也可用;

C/C++新手入门项目合集:GitHub资源库0voice/introduce_c-cpp_manual详解 C/C++作为系统级编程语言,其核心价值在于对计算机底层原理的深入理解和高效控制。从内存管理、指针操作到数据结构与算法,掌握这些基础概念是构建高性能应用的关键。在工程实践中,理论学习之后往往面临“如何将知识转化为实际项目”的痛点。开源社区为此提供了丰富的练手资源,其中GitHub上的项目合集成为开发者从入门到进阶的重要桥梁。这些资源覆盖了网络编程、并发处理、图形界面等核心应用场景,通过阅读和修改真实代码,能够有效提升工程思维和调试能力。本文聚焦的 `0voice/introduce_c-cpp_manual 阅读详情

相关推荐

C++ Socket编程实战:从零构建多人聊天室,掌握网络与并发核心

网络编程是现代软件开发的基础,其核心在于实现不同主机间的进程通信。其基本原理是通过套接字(Socket)建立连接,在TCP/IP协议栈上传输数据。这项技术的价值在于支撑了从即时通讯到分布式系统的一切网络应用。在工程实践中,一个经典的练手项目是构建一个C/S架构的聊天室,它能直观地串联起**Socket编程**、**多线程同步**等核心概念。通过实现服务器对多个客户端连接的管理、消息的接收与广播,开发者可以深入理解**I/O模型**、线程安全以及TCP粘包等实际问题。本项目以C++11/14为基础,采用清晰的

weixin_30697239的博客 365

WSL2环境C++ TCP聊天服务器实战:select多路复用与Socket编程详解

网络编程是构建分布式系统的核心技术,其核心在于实现不同主机间的进程通信。TCP/IP协议栈提供了可靠的字节流传输服务,而Socket API则是应用层与传输层之间的编程接口。通过Socket编程,开发者可以创建客户端-服务器模型的应用,实现数据交换。在并发处理方面,I/O多路复用技术如select、poll和epoll能够有效管理多个连接,提升服务器性能。这些技术在高并发服务器、实时通信系统和物联网网关等场景中具有重要价值。本文聚焦于在WSL2环境中,使用C++和select机制实现一个支持多客户端的TCP

weixin_30570101的博客 371

C++网络编程实战:从零构建C/S架构多人聊天室

网络编程是构建分布式系统的核心技术,其核心在于实现不同主机间的进程通信。在众多网络模型中,客户端/服务器(C/S)架构因其逻辑清晰、易于管理而成为经典范式,尤其适用于需要集中控制和状态维护的应用场景。通过Socket API,程序可以建立可靠的端到端连接,其中TCP协议凭借其面向连接、可靠传输和有序交付的特性,成为需要保证数据完整性的应用(如即时通讯、文件传输)的首选。结合多线程技术,服务器能够高效处理并发连接,利用线程池管理资源,避免频繁创建销毁线程的开销,从而提升系统吞吐量和响应能力。这种技术组合在构建

weixin_34211761的博客 299

Windows下select模型

https://blog.youkuaiyun.com/hq354974212/article/details/76154849 阻塞模式和非阻塞模式的优点和不足:        阻塞模式套接字执行IO操作时,如果执行操作的条件未满足,线程就会阻塞在调用的函数上。程序不得不处于等待状态,但是由于并不知道客户请求何时到来,因此函数在何时返回不得而知。       非阻塞模式套接字执行IO操作时,在任何...

波波诸葛伟 4728

从零封装C++ TCP通信框架:掌握Socket编程核心与C/S模型实践

网络编程是构建分布式系统和后台服务的核心技术,其基础在于理解TCP/IP协议栈和Socket编程模型。TCP协议通过三次握手建立可靠连接,并提供有序、无差错的字节流传输,而Socket则是操作系统提供的网络编程接口,允许应用程序通过文件描述符进行网络通信。掌握Socket编程对于实现客户端-服务器(C/S)架构至关重要,它能帮助开发者构建从即时通讯到游戏服务器等各种网络应用。在实际工程中,直接使用原生Socket API常面临错误处理繁琐、数据边界模糊和跨平台兼容性等挑战。通过封装可复用的TcpClient

aiqixiao2017的博客 415

Linux下Socket网络接口编程(C++)

Linux受到广泛运用,一个重要的原因就是其强大的网络功能。SOCKET用于在两个基于TCP/IP协议的应用程序之间相互通信。最早出现在UNIX系统中,是UNIX系统主要的信息传递方式。在WINDOWS系统中,SOCKET称为WINSOCK。        两个基本概念:客户方和服务方。当两个应用之间需要采用SOCKET通信时,首先需要在两个应用之间(可能位于同一台机器,也可能位于不同的机器)建

workhorse的专栏 1564

5种Windows网络模型之select模型

  在Windows环境下用C语言实现CS模型中我们详细介绍了网络通信中需要使用的几个函数并指出了最基本的CS模型存在的缺点,为了克服这些缺点,人们提出了select模型,select模型和CS模型相比有以下几个优势: 解决了基本CS模型中accept与recv函数等待连接和等待消息时程序的阻塞。 实现多个客户端连接,能够接收多个客户端的消息 select模型仅用于服务器端 1. select模型原理 每个客户端都有一个socket,服务器也有自己的socket,将所有的socket放进一个数据结构里

nthzduang_的博客 4326

c/c++之windows基于select搭建一个socket服务器(亲测可用)

【代码】c/c++之windows基于select搭建一个socket服务器(亲测可用)

我不是码农的博客~~~ 1375

Windows与Linux下的select网络模型对比分析

详尽分析了Windows与Linux下的select模型的不同,各自的实现原理,各自的优点以及一些改进的建议。附有封装好的模型代码和相关注释

走在成长的路上 2492

从模型车到真实路口:基于YOLOv5-Lite与SORT的轻量化车流量检测系统实战

本文详细阐述了如何将基于YOLOv5-Lite与SORT的轻量化车流量检测系统从毕业设计原型部署到真实路口。文章聚焦于解决在嵌入式平台(如树莓派)上实现实时、稳定检测的工程挑战,涵盖数据采集、模型微调、系统集成及动态信号灯策略,为智能交通灯系统提供了实用的轻量化解决方案。

weixin_29179311的博客 126

红外热成像仪原理及应用

目录什么是红外热成像背景介绍热成像技术原理热成像分类红外热成像和夜视仪之间的区别红外热像仪夜视仪红外照明相机对比红外热像仪都能看透什么如何选择制冷型和非制冷型红外热像仪制冷型红外热像仪非制冷型红外热像仪实例对比成像速度空间分辨率灵敏度光谱滤波同步何如选择合适的红外热像仪像素测温范围和被测物温度分辨率空间分辨率温度稳定性热像仪的距离系数比常见热成像仪关键参数量程视场角 (FOV)红外分辨率热灵敏度(NETD)焦距光谱范围精度内置优化分析NTED(热灵敏度)什么是NETD如何测量NETD?NETD如何影响测量?

zhy295006359的博客 2万+

windows的select函数

select的大概思想:将多个套接字放在一个集合里,然后统一检查这些套接字的状态(可读、可写、异常等),调用select后,会更新这些套接字的状态,然后做判断,如果套接字可读,就执行read操作。这样就巧妙地避免了阻塞,达到同时处理多个连接的目的。当然如果没有事件发生,select会一直阻塞,如果不想一直让它等待,想去处理其它事情,可以设置一个最大的等待时间。 int sel

stone-jin 7005

静态时序分析(STA)_深入解析Data to Data Checks的零周期挑战

本文深入解析了静态时序分析(STA)中Data to Data Checks的核心概念与零周期挑战。重点探讨了当Setup要求值超过时钟周期时,工具如何调整发射沿,并导致Hold检查的发射与捕获沿“分裂”这一反直觉现象。文章通过案例详细解读了时序报告,并提供了通过调整约束或接受多周期保持两种策略来应对这一挑战,帮助工程师正确理解和处理此类复杂时序检查。

weixin_29204205的博客 351

Windows I/O模型之一:Select模型

1.概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock) 四种调用模式: 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果前,该调用就不返回。也就是必须一件 一件做事,等前一件做完了才能做另一件。 例如在C/S模式的某个流程中,你服务器提交了某个请求,在服务器处理完毕返回结果期间客户端什...

234

Docker部署FRP实现内网穿透

FRP是一款开源内网穿透工具,通过在公网服务器部署服务端(FRPS),内网设备运行客户端(FRPC)实现外部访问。支持TCP、UDP、HTTP等多种协议。部署时需配置服务端(如群晖NAS使用Docker)和客户端(如Windows下载可执行文件)。服务端需设置监听端口、控制面板及Token认证,客户端需指定服务器地址和相同Token。完成配置后可通过公网IP或域名访问内网资源,并在控制面板监控连接状态。

波哥技术栈 1601

Shader Graph实战:5分钟搞定Flow Map水体流动效果(含UV偏移避坑指南)

本文详细解析了如何使用Unity的Shader Graph工具快速实现Flow Map水体流动效果,涵盖基础原理、核心节点搭建、高级技巧及性能优化。特别针对UV偏移问题提供避坑指南,帮助开发者轻松打造专业级动态水面效果,适合游戏场景增强视觉表现。

weixin_29250403的博客 245

C++ Windows Socket五种I/O模型

Windows Socket五种I/O模型 Winsock 的I/O操作: 1、 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK...

qq_24127015的博客 891

计算机补码两位乘法移位补0还是1,补码两位乘.doc

补码两位乘沈阳航空航天大学课 程 设 计 报 告课程设计名称:计算机组成原理课程设计课程设计题目:COP2000实现补码两位乘法院(系):计算机学院专 业:计算机科学与技术(嵌入式系统方向)班 级学 号:2009040101181姓 名:张驰指导教师:杨华完成日期:2012年1月14日目 录第1章 总体设计方案11.1设计原理11.2设计思路11.3设计环境2第2章...

weixin_34471838的博客 968

C++ Socket编程实战:基于select实现高效多客户端服务端

I/O多路复用是网络编程中解决高并发连接的核心技术,其原理是通过单个进程同时监视多个文件描述符,当任一描述符就绪时,内核通知进程进行读写操作,从而避免为每个连接创建独立线程带来的资源消耗和上下文切换开销。这项技术能显著提升系统的并发处理能力和资源利用率,广泛应用于游戏服务器、即时通讯、数据采集等需要同时处理大量连接的场景。在具体实现中,select作为最经典且跨平台的I/O多路复用模型,通过fd_set管理套接字集合,配合SO_REUSEADDR选项可有效解决“Address already in use”

weixin_30372371的博客 513

使用 vLLM 和 YaRN 扩展技术部署 Qwen3-32B 大模型:实现 80K 长文本推理

vLLM 是一个高性能的 LLM 推理和服务引擎,以其高效的注意力机制(PagedAttention)和优异的内存管理著称。它提供了与 OpenAI API 兼容的接口,使得现有应用可以无缝迁移。通过vLLM与YaRN技术的结合,我们成功将Qwen3-32B的上下文处理能力从32K扩展到80K,为长文本应用场景提供了强大的技术支持。这种部署方案兼具高效性和实用性,是处理大模型长上下文需求的优选方案。随着硬件和算法的不断进步,我们期待看到更大上下文窗口的模型服务成为可能。延伸阅读vLLM官方文档。

Ven%的博客 1749

SSD |(二)SSD主控

控制器作为一个片上系统,处理来自用户端的命令并负责管理闪存颗粒。

知识库搭建ing 1963

【C/C++】windows 下的 socket API 编程(TCP协议)

0w0准备(以 winsock2 为例)流程服务端简介客户端简介服务端实现流程未完待续... 准备(以 winsock2 为例) winsock2 即 windows socket 2,2 是版本号,对应的还有 winsock 常用函数   WSAStartup () int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); ...

高厉害 0w0 1272

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C/C++网络编程:编写一个简单的聊天对话程序

这段代码设置地址的相关信息,其中,hints.ai_family设置的是采用IPV4还是IPV6地址,这里设置成AF_UNSPEC也就是没有特别指定地址类型,也就表明IPV4和IPV6都会用到,同时在创建socket后,还得设置socket选项,利用setsockopt(socket_listen, IPPROTO_IPV6, IPV6_V6ONLY, nullptr, 0),这个函数目的就是将IPV6_V6ONLY这个标志设置为空(最后两个参数),表明可以接受IPV4地址。

DreamXY12的博客 927

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++ Socket网络编程 1.3版本 将服务端升级为Select模型处理多客户端

在之前的版本(1.1和1.2)中,服务端和客户端都是1对1的阻塞模型网络程序,例如服务端的accept,recv都是阻塞等待。一个最大的问题是,当服务端阻塞时,不能处理其它的业务,从而无法实现一个服务端处理多个客户端的功能。因此,将服务端升级为Select模型处理多客户端的网络请求。 Select网络模型是Linux、Windows、IOS、安卓等操作系统中标准C/C++支持的网络通信模型,内部会...

La745739773的博客 757

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

2024年Windows Socket编程实战:现代C++实现高性能TCP服务器

网络编程是构建分布式系统和网络应用的核心技术,其底层基石是Socket(套接字)通信机制。Socket作为操作系统提供的网络编程接口,封装了TCP/IP协议栈的细节,实现了不同主机间进程的数据交换。理解Socket的工作原理,如三次握手、数据流、阻塞与非阻塞模式,是优化网络性能、设计高并发服务的关键。在物联网、游戏服务器、高频交易等对性能和可控性要求极高的领域,原生Socket配合C/C++仍是不可替代的技术方案。本文以Windows平台为例,结合现代C++的RAII、智能指针和多线程特性,深入解析Wins

weixin_34275734的博客 426

C++ 实现基于 select 的 TCP 并发服务器

在传统的阻塞模型中,一个线程只能等待一个 socket 上的 I/O 事件。如果同时管理 100 个连接,要么开 100 个线程(开销大),要么轮询每个 socket(CPU 空转)。用一个系统调用,同时监视多个文件描述符(fd),谁就绪就处理谁。机制特点select历史悠久,跨平台,有 fd 数量上限(通常 1024),每次调用需拷贝 fd 集合poll改进了 select 的部分限制,但仍需遍历全部 fdepollLinux 高性能方案,适合大量连接,边缘触发/水平触发本文选择select。

fighting_88412的博客 371
上一篇: windows C/C++ socket (一对一)
下一篇: C/C++ 二级指针与一级指针 (作用在参数传递时 VC)
__网瘾少年
博客等级 码龄11年 122粉丝 103原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值