tcp和udp多线程的epoll服务器+客户端源代码

【原创】性能炸裂c++20协程+iocp/epoll,C++20无栈协程超轻量高性能异步库开发实战 主要讲述c++20协程库开发的实战过程和思路方法,比较干货,后面有源码。刚学也有很多不足,希望大佬指正。 阅读详情

程序是从网上的一个epoll例子修改而来的

epoll tcp服务端 epoll_server.c:

/*
gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I${ORACLE_HOME}/rdbms/public -I${ORACLE_HOME}/rdbms/demo -L${ORACLE_HOME}/lib -lclntsh  -pthread -o epoll_server epoll_server.c
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
#include
#include
#include
#include

//#include "oci_api.h"

#define MAXBUF 1024
#define MAXEPOLLSIZE 10000

/*
setnonblocking - 设置句柄为非阻塞方式
*/
int setnonblocking(int sockfd)
{
    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
        return -1;
    }
    return 0;
}

/*
handle_message - 处理每个 socket 上的消息收发
*/
int handle_message(int new_fd)
{
    char buf[MAXBUF + 1];
    char sendbuf[MAXBUF+1];
    int len;
    /* 开始处理每个新连接上的数据收发 */
    bzero(buf, MAXBUF + 1);
    /* 接收客户端的消息 */
    len = recv(new_fd, buf, MAXBUF, 0);
    if (len > 0){

        printf
            ("%d接收消息成功:'%s',共%d个字节的数据/n",
             new_fd, buf, len);
   /*

        char *s1="insert";
        char *s2="select";
        char *s3="delete";

    if(!strncmp(s1,buf,6))
        oci_insert(buf,sendbuf);
    else if(!strncmp(s2,buf,6))
        oci_select(buf,sendbuf);
    else if(!strncmp(s3,buf,6))
        oci_delete(buf,sendbuf);
    else
        sprintf(sendbuf,"input sql is error!/n");

        len=send(new_fd,sendbuf,strlen(sendbuf),0);
        if(len<0)
     printf("消息发送失败!错误代码是%d,错误信息是'%s'/n",

                      errno, strerror(errno));

  */
    }
    else {
        if (len < 0)
            printf
                ("消息接收失败!错误代码是%d,错误信息是'%s'/n",
                 errno, strerror(errno));
else
    printf
  ("客户端%d退出!/n",new_fd);
        //close(new_fd);
        return -1;
    }
    /* 处理每个新连接上的数据收发结束 */
    return len;
}
/************关于本文档********************************************
*filename: epoll-server.c
*purpose: 演示epoll处理海量socket连接的方法
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-31 21:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:Google
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
    int listener, new_fd, nfds, n, ret;
    struct epoll_event ev;
    int kdpfd, curfds;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    struct epoll_event events[MAXEPOLLSIZE];
    struct rlimit rt;

    if (argc>1)
        myport = atoi(argv[1]);
    else
        myport = 1234;

    if (argc>2)
        lisnum = atoi(argv[2]);
    else
        lisnum = 10;

    /* 设置每个进程允许打开的最大文件数 */
    rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
    if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {
        perror("setrlimit");
        exit(1);
    }
    else printf("设置系统资源参数成功!/n");

    /* 开启 socket 监听 */
    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    } else
        printf("socket 创建成功!/n");

    /*设置socket属性,端口可以重用*/
    int opt=SO_REUSEADDR;
    setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    /*设置socket为非阻塞模式*/
    setnonblocking(listener);

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(myport);
    if (argc>3)
        my_addr.sin_addr.s_addr = inet_addr(argv[3]);
    else
        my_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind
        (listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
        == -1) {
        perror("bind");
        exit(1);
    } else
        printf("IP 地址和端口绑定成功/n");

    if (listen(listener, lisnum) == -1) {
        perror("listen");
        exit(1);
    } else
        printf("开启服务成功!/n");

    /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
    kdpfd = epoll_create(MAXEPOLLSIZE);
    len = sizeof(struct sockaddr_in);
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = listener;
    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0) {
        fprintf(stderr, "epoll set insertion error: fd=%d/n", listener);
        return -1;
    } else
        printf("监听 socket 加入 epoll 成功!/n");
    curfds = 1;
    while (1) {
        /* 等待有事件发生 */
        nfds = epoll_wait(kdpfd, events, curfds, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            break;
        }
        /* 处理所有事件 */
        for (n = 0; n < nfds; ++n) {
            if (events[n].data.fd == listener) {
                new_fd = accept(listener, (struct sockaddr *) &their_addr,
                                &len);
                if (new_fd < 0) {
                    perror("accept");
                    continue;
                } else
                    printf("有连接来自于: %s:%d, 分配的 socket 为:%d/n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);

                setnonblocking(new_fd);
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = new_fd;
                if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0) {
                    fprintf(stderr, "把 socket '%d' 加入 epoll 失败!%s/n",
                            new_fd, strerror(errno));
                    return -1;
                }
                curfds++;
            } else {
                ret = handle_message(events[n].data.fd);
                if (ret < 1 && errno != 11) {
                    if(epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,
                              &ev) < 0)
             {
             fprintf(stderr, "把 socket '%d' 从 epoll 删除失败!%s/n",
                     events[n].data.fd, strerror(errno));
             }
                    curfds--;
      close(events[n].data.fd);
                }
            }
        }
    }
    close(listener);
    return 0;
}

tcp客户端client.c:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define MAXLINE 1024
char sendhead[MAXLINE];

int main(int argc , char* argv[])

{
int sockfd;

struct sockaddr_in servaddr;

char *info="cxt";
int   maxfdp1, stdineof;
fd_set  rset;
char  recvbuf[MAXLINE],tmp[128],sendbuf[MAXLINE];
int             n,len,fd;

if(argc!=3){
printf("useage:client address port ");
exit(0);
}

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1  )

{
  perror("socket");
  exit(1);
}
   printf("%s connect server/n",info);
   bzero(&servaddr,sizeof(servaddr));
   servaddr.sin_family=AF_INET;
   servaddr.sin_port=htons(atoi(argv[2]));
   inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
   if( ( connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))  )<0)
   {
     perror("connect");
     exit(1);
   }
send(sockfd,info,strlen(info),0);
//FD_ZERO(&rset);
//FD_SET(sockfd, &rset);
        //FD_SET(0, &rset);
//maxfdp1=sockfd+1;
for ( ; ; ) {
  FD_ZERO(&rset);
  FD_SET(sockfd, &rset);
         FD_SET(0, &rset);
  maxfdp1=sockfd+1;

  if(  ( select(maxfdp1, &rset, NULL, NULL, NULL) )<=0){
      perror("select");
  }else{
  if (FD_ISSET(0,&rset)){
                        fgets(sendbuf, MAXLINE, stdin);
                        n=send(sockfd,sendbuf,strlen(sendbuf)-1,0);
                        if(n>0)
                                printf("send: %s",sendbuf);
                        else
                                printf("send: %s error,the erro cause is %s:%s/n",sendbuf,errno,strerror(errno));
   bzero(sendbuf,strlen(sendbuf));

                }

  if (FD_ISSET(sockfd, &rset)) { /* socket is readable */
   n=recv(sockfd, recvbuf, MAXLINE,0) ;
                      if(n<0) {
    perror("str_cli: server terminated prematurely");
   }else if(n==0)
    {
    printf("sever shutdown!");
    exit(-1);
    }
   //recvbuf
   recvbuf[n]='/0';
   printf("receive :%s/n",recvbuf);
   fflush(stdout);
   bzero(recvbuf,strlen(recvbuf));
  }
  }
}

       exit(0);
}

udp +epoll+多线程服务器 udp_epoll_server.c:

/*
gcc -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I${ORACLE_HOME}/rdbms/public -I${ORACLE_HOME}/rdbms/demo -L${ORACLE_HOME}/lib -lclntsh  -pthread -o udp_epoll_server udp_epoll_server.c -lpthread
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
#include
#include
#include
#include
#include
#include

//#include "oci_api.h"

#define MAXBUF 1024
#define MAXEPOLLSIZE 100

/*
   setnonblocking – 设置句柄为非阻塞方式
   */
int setnonblocking(int sockfd)
{
    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
    {
        return -1;
    }
    return 0;
}

/*
   pthread_handle_message – 线程处理 socket 上的消息收发
   */
void* pthread_handle_message(int* sock_fd)
{
    char recvbuf[MAXBUF + 1];
    char sendbuf[MAXBUF+1];
    int  ret;
    int  new_fd;
    struct sockaddr_in client_addr;
    socklen_t cli_len=sizeof(client_addr);

    new_fd=*sock_fd;
    /* 开始处理每个新连接上的数据收发 */
    bzero(recvbuf, MAXBUF + 1);
    bzero(sendbuf, MAXBUF + 1);
    /* 接收客户端的消息 */
    ret = recvfrom(new_fd, recvbuf, MAXBUF, 0, (struct sockaddr *)&client_addr, &cli_len);
    if (ret > 0)
    {
        printf("socket %d 接收到来自:%s:%d的消息成功:’%s’,共%d个字节的数据/n",
             new_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recvbuf, ret);
/* char *s1="insert";
    char *s2="select";
    char *s3="delete";

    if(!strncmp(s1,recvbuf,6))
        oci_insert(recvbuf,sendbuf);
    else if(!strncmp(s2,recvbuf,6))
        oci_select(recvbuf,sendbuf);
    else if(!strncmp(s3,recvbuf,6))
        oci_delete(recvbuf,sendbuf);
    else
        sprintf(sendbuf,"input sql is error!/n");

ret = sendto(new_fd, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&client_addr, cli_len);
        if(ret<0)
            printf("消息发送失败!错误代码是%d,错误信息是'%s'/n",
                            errno, strerror(errno));
   */

    }
    else
    {
            printf("消息接收失败!错误代码是%d,错误信息是’%s’/n",
                 errno, strerror(errno));
    }
    /* 处理每个新连接上的数据收发结束 */
    //printf("pthread exit!");
    fflush(stdout);
    pthread_exit(NULL);
}

int main(int argc, char **argv)
{
    int listener, kdpfd, nfds, n, curfds;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport;
    struct epoll_event ev;
    struct epoll_event events[MAXEPOLLSIZE];
    struct rlimit rt;

    myport = 1234;

    pthread_t thread;
    pthread_attr_t attr;

    /* 设置每个进程允许打开的最大文件数 */
    rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
    if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
    {
        perror("setrlimit");
        exit(1);
    }
    else
    {
        printf("设置系统资源参数成功!/n");
    }
    /* 开启 socket 监听 */
    if ((listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
    {
        perror("socket 创建失败!");
        exit(1);
    }
    else
    {
        printf("socket 创建成功!/n");
    }

    /*设置socket属性,端口可以重用*/
    int opt=SO_REUSEADDR;
    setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    setnonblocking(listener);
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(myport);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("bind");
        exit(1);
    }
    else
    {
        printf("IP 地址和端口绑定成功/n");
    }

    /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
    kdpfd = epoll_create(MAXEPOLLSIZE);
    len = sizeof(struct sockaddr_in);
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = listener;
    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0)
    {
        fprintf(stderr, "epoll set insertion error: fd=%d/n", listener);
        return -1;
    }
    else
    {
        printf("监听 socket 加入 epoll 成功!/n");
    }
    while (1)
    {
        /* 等待有事件发生 */
        nfds = epoll_wait(kdpfd, events, 10000, -1);
        if (nfds == -1)
        {
            perror("epoll_wait");
            break;
        }
        /* 处理所有事件 */
        for (n = 0; n < nfds; ++n)
        {
            if (events[n].data.fd == listener)
            {
                /*初始化属性值,均设为默认值*/
                pthread_attr_init(&attr);
                pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
                /*  设置线程为分离属性*/
                pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

                if(pthread_create(&thread,&attr,(void*)pthread_handle_message,(void*)&(events[n].data.fd)))
                {
                        perror("pthread_creat error!");
                        exit(-1);
                }
            }
        }
    }
    close(listener);
    return 0;
}

udp客户端 udp_client.c:

#include
#include
#include
#include
#include
#include
#include
#include

#define MAXLINE 1024
#define SERV_PORT 1234

void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + 1];

/* connect to server */
if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
{
perror("connect error");
exit(1);
}

while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
write(sockfd, sendline, strlen(sendline)-1);
/* receive data from server */
n = read(sockfd, recvline, MAXLINE);
if(n == -1)
{
perror("read error");
exit(1);
}
recvline[n] = '/0'; /* terminate string */
//fputs(recvline, stdout);
printf("receive:%s/n",recvline);
fflush(stdout);

}
}

int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;

/* check args */
if(argc != 2)
{
printf("usage: udpclient /n");
exit(1);
}

/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
printf("[%s] is not a valid IPaddress/n", argv[1]);
exit(1);
}

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

return 0;
}

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/seven407/archive/2009/12/13/4985146.aspx

基于Socket的网络即时通信系统设计与实现 即时通信系统的本质是“状态同步”与“事件通知”,无论是文本聊天、图片分享还是系统指令下发,所有交互都必须建立在一个清晰、一致且具备扩展能力的消息模型之上。因此,在设计底层通信协议之前,首先需要从逻辑层面明确每条消息所承载的信息维度及其组织方式。在第五章定义的消息框架基础上,可扩展专用的心跳类型。 阅读详情

相关推荐

携程旅行网景区,评论数据爬虫项目数据库保存附源码

这是一个专门用于爬取某旅行网景区评论数据的Python爬虫项目。项目采用模块化设计,支持MySQL数据库存储,具备完整的异常处理机制和反爬虫策略。

ymqzhy的博客 2568

IO多路复用:select机制,poll机制,epoll机制(C语言)

大家好,我是练习编程时长两年半的个人练习生昆工第一ikun,今天我们来分享一下如何让TCP通信可以像UDP那样做到多个客户端可以同时与服务器进行通信,我们可以使用非阻塞模式和多进程多线程,但是这两种方法有其弊端,下面我们将介绍一种弊端较少的方法——IO多路复用。

weixin_65155181的博客 1625

基于WEB的报价管理系统的设计与实现

该系统采用B/S模式,后台运用SpringMVC和MyBatis搭建,利用MySQL数据库,来组织存储和管理数据,使用tomcat服务器向外提供服务。使用该系统对外有利于提高企业的综合竞争力,对内有利于提高成本管理和控制的水平,简化了报价流程、提高了工作效率、精简了报价机构,降低了成本。研究和掌握必要的信息采集和数据查询技术,是各个企业,事业单位信息化的一个重要标志。当前大多数企业采取的报价方式仍然是用EXCEL表格和人工的方式,这不仅不利于大量数据的总结,更不利于对销售利润的控制。

m0_60918862的博客 999

使用epoll实现客户端UDP并发

g++ -o  udp_epoll_c udp_epoll_c.cpp -lpthread /*************************************************************************** file: udp_epoll_c.cpp -------------------

呆龙的专栏 1761

【MATLAB】绘制泽尼克多项式

上次只给了公式没有给代码,很多小伙伴表示不是很认可。今天直接把代码发上来了。

HPC_ZY 5576

评分卡建模学习(一)————数据预处理part.3

目录六、数据处理的思路及代码(一)对缺失值的处理:在我这个数据预处理的part.1板块(二)对异常值的处理:在我这个数据预处理的part.2板块(三)数据归一化、标准化:在我这个数据预处理的part.2板块(四)非结构化数据转变+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++———————————————————————————————————————————++++++++++++++++++++++++++

Morven_dai的博客 898

C语言之网络编程(必背知识点)

提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。

qq_52049228的博客 6219

华为OD技术面真题 - Python开发 - 1

汇总华为OD技术面八股Python八股,高频技术真题并提供详细解答。

qq_45776114的博客 1717

(c语言)即时通讯系统---epoll+线程池 版本

epoll1.相比较: select内部使用数组实现,poll是链表。他们需要做内核区到用户区的转换,还需要做数据拷贝,因此效率低2.epoll不需要做内核区到用户区的转换,因为数据存在共享内存中。epoll维护的树在共享内存中,内核区和用户区去操作共享内存,因此不需要区域转换,也不需要拷贝操作。线程池(1)降低销毁资源:重复利用线程池中已经存在的线程,减少了线程的创建和消亡造成的性能开销。(2)提高了相应速率:当任务到达时,任务可以不需要等到线程创建就能够执行。

m0_70681152的博客 4097

嵌入式系统开发笔记112:通过有人云测试MQTT

项目中使用到“有人”公司的WH-LTE-7S0模块,本文讲解通过有人云进行MQTT测试的方法。

snmplink的博客 997

4、LTE无人机认证:保障通信安全的新方案

本文针对LTE网络中无人机通信存在的安全风险,提出了一种基于可信第三方GCS的新型认证协议。该协议通过非对称加密和哈希函数保护IMSI等敏感信息,防止身份泄露、中间人攻击、拒绝服务攻击和位置追踪等威胁。利用Scyther工具对协议进行形式化分析,验证了其在机密性、一致性和活性等方面的安全属性,证明该方案能有效提升无人机在LTE网络中的通信安全性与隐私保护能力。

pink的博客 60

udp epoll服务器的设计

在做udp服务器的时候,如何处理来自多个连接的udp请求呢?本文介绍udp+epoll服务器的网络框架设计方法

occupy8的专栏 1227

VHDL六层电梯控制器及仿真

六层电梯电梯 设计要求:设计一个六层电梯控制系统要求有超载、关门中断、提前关门清除报警信电梯外人的上升请求信号,电梯外人的下降请求信号, 电梯外人上升请求信号显示电梯外人下降请求信号显示到达楼层信号 设计思路:输入有clk时钟信号(频率为2Hz) full,deng,quick,clr超载、关门中断、提前关门清除报警c_u1,c_u2,c_u3,c_u4,c_u5电梯外人的上升请求c_d2,c_d3,c_d4,c_d5,c_d6 电梯外人的下降请求 d1,d2,d3,d4,d5,d6电梯内人的...

QQ_778132974的博客 1709

tcp和udp多线程的epoll服务器+客户端源代码 - brucema的个人空间 - 开源中国社区

tcp和udp多线程的epoll服务器+客户端源代码 - brucema的个人空间 - 开源中国社区 tcp和udp多线程的epoll服务器+客户端源代码 - brucema的个人空间 - 开源中国社区tcp和udp多线程的epoll服务器+客户端源代码 ...

123

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

linux高性能服务器编程之同时处理UDP请求和TCP请求的服务器

源代码如下:#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <assert.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #in

脚踏实地,不断突破自我,每天有收获就OK 1059

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

基于epoll实现的c++聊天室(全代码)

早些时候为了更加熟悉网络编程,所以写了一个聊天程序练练手,但那是纯linux终端实现的,没有界面,最近心血来潮翻出来加了个Qt的简单界面,成了一个简易的局域网聊天室,通过tcp服务器来转发消息,其实最初实现的时候无界面情况下已经实现了单聊群聊文件传输,udp文件传输还实现了补包重传(udp虽然不可靠传输但是比tcp牛逼),有兴趣的同学可以一起来学习和交流。如果有时间的话我会拓展一下其他的功能,包括...

FlayHigherGT的博客 3752

i.MX6ULL嵌入式Linux网络Socket编程实战:从TCP/UDP到并发服务器

Socket编程是网络通信的基础,它通过系统调用为应用程序提供了访问网络协议栈的统一接口,其核心原理在于建立连接、数据传输和端口管理。掌握Socket编程对于构建分布式系统和实现设备互联具有重要技术价值,尤其在物联网和工业控制等嵌入式应用场景中,它是设备与云端、设备与设备间可靠数据交换的关键。在资源受限的嵌入式平台上,如基于ARM Cortex-A7架构的NXP i.MX6ULL,进行Socket编程时,开发者需重点关注**交叉编译**环境的搭建、**TCP/UDP**协议的选择与实现,以及如何通过多进程或

weixin_34110749的博客 476

C语言网络编程探秘

最近在阅读Redis源代码的网络IO模型,于是想写一篇socket通信的文章,以总结一下。但是我又不想自己从头写,毕竟从写例子到组织语言需要耗费太多的时间,而且我组织的语言通常比较啰嗦。我想到我平时经常用到AI编程工具,于是我在`百度文心快码`、`腾讯云 AI 代码助手`、`MarsCode AI `提出了以下问题,要他们写一篇关于C语言网络编程的博客,本文就是在这三个AI编程工具写的博客基础上做的一些修改,并将举的例子在本地运行了。

风清扬zld的博客 1212
上一篇: vc++实现无进程无DLL无硬盘文件无启动项的ICMP后门后门程序
下一篇: 抄写了一次ping程序
wind0513
博客等级 码龄24年 3粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值