当前位置: 首页 > article >正文

Linux网络编程之---多线程实现并发服务器

下面我们来使用tcp集合多线程实现并发服务器

一.服务端

#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

typedef struct sockinfo
{
    char ip[16];
    unsigned short port;
}sockinfo;
sockinfo s;
void *working(void *arg)
{
    //子线程和客户端通信
    int fd = *(int *)arg;
    printf("%d\n",fd);
    char recv_buff[1024];
    printf("接收到新的客户端,ip:%s,端口:%d\n",s.ip,s.port);
    while(1)
    {
        int len = read(fd,recv_buff,sizeof(recv_buff));
        if(len > 0)
        {
            printf("接收到新的客户端的数据:%s\n",recv_buff);
            len = write(fd,recv_buff,strlen(recv_buff));
        }
        else if(len == -1)
        {
            perror("read");
                break;
        }
        else if(len == 0)
        {
            printf("客户端断开连接\n");
            break;;
        }       
    }
    close(fd);
    return NULL;
}
int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        perror("socket");
        exit(-1);
    }
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8000);
    if(bind(sockfd,(const struct sockaddr*)&server,sizeof(server)) == -1)
    {
        perror("bind");
        exit(-1);
    }

    if(listen(sockfd,8) == -1)
    {
        perror("listen");
        exit(-1);
    }

    //循环等待客户端连接,一旦有客户端连接进来就创建一个子线程连接进来
    struct sockaddr_in client;
    socklen_t client_addr_len = sizeof(client);
    int client_fd;
    char client_ip[16];
    unsigned short client_port;
    while(1)
    {
        client_fd = accept(sockfd,(struct sockaddr*)&client,&client_addr_len);
        if(client_fd == -1)
        {
            perror("accept");
            exit(-1);
        }
        inet_ntop(AF_INET,(const void *)&client.sin_addr.s_addr,client_ip,sizeof(client_ip));
        client_port = ntohs(client.sin_port);

        memcpy(s.ip,client_ip,sizeof(client_ip));
        s.port = client_port;

        //创建线程
        pthread_t tid;
        pthread_create(&tid,NULL,working,(void *)&client_fd);

        pthread_detach(tid);
    }
    close(sockfd);
    return 0;
}

二.客户端

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1)
    {
        perror("socket");
        exit(-1);
    }
    struct sockaddr_in client;
    client.sin_family = AF_INET;
    client.sin_addr.s_addr = inet_addr("127.0.0.1");
    client.sin_port = htons(8000);
    if(connect(sockfd,(const struct sockaddr*)&client,sizeof(client)) == -1)
    {
        perror("connect");
        exit(-1);
    }

    //写
    char *client_send_data;
    char client_recv_buf[1024];
    int len;
    while(1)
    {
        printf("亲爱的用户,请发送你要发送给服务器的数据:");
        scanf("%s",client_send_data);
        len = write(sockfd,client_send_data,strlen(client_send_data));
        if(len == -1)
        {
            perror("write");
            break;
        }

        memset(client_recv_buf,0,sizeof(client_recv_buf));
        len = read(sockfd,client_recv_buf,sizeof(client_recv_buf));
        if(len == -1)
        {
            perror("read");
            break;
        }
        else if(len > 0)
        {
            printf("接收到服务器端的回射数据:%s\n",client_recv_buf);
        }
        else if(len == 0)
        {
            printf("服务器断开连接\n");
            break;
        }
        sleep(1);
    }
    close(sockfd);
    return 0;
}

三.运行效果

可以发现我们使用tcp结合多线程的服务器可以同时接收多个客户端的连接,并且可以同时收发数据.


http://www.kler.cn/a/421471.html

相关文章:

  • 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)
  • ultralytics-YOLOv11的目标检测解析
  • MySQL常见面试题(二)
  • 学习threejs,使用VideoTexture实现视频Video更新纹理
  • 开源ISP介绍(1)——开源ISP的Vivado框架搭建
  • idea打jar包或引入包
  • 【北京迅为】iTOP-4412全能版使用手册-第三十二章 网络通信-TCP套字节
  • 嵌入式蓝桥杯学习1 点亮LED
  • LabVIEW 队列消息处理器设计
  • 云计算介绍_02(虚拟化、虚拟化类型、虚拟化层架构、容器)
  • 鸿蒙多线程开发——Sendable使用注意事项
  • 【docker】docker compose多容器部署
  • Rain后台权限管理系统,快速开发
  • 我的知识图谱和Neo4j数据库的使用
  • AI×5G 市场前瞻及应用现状
  • 深入探索 HarmonyOS 的 Navigation 组件:灵活的页面管理与动态导航
  • win10-Docker打不开this can prevent Docker from starting. Use at your own risk.
  • 【C++】LeetCode:LCR 022. 环形链表 II
  • 数字图像处理(13):图像裁剪
  • 银河麒麟V10-SP1设置redis开机自启
  • Web安全基础实践
  • 论文阅读:Single-cell transcriptomics of 20 mouse organs creates a Tabula Muris
  • 【docker】Overlay网络
  • 【分页查询】.NET开源 ORM 框架 SqlSugar 系列
  • ceph的用户管理和cephx认证
  • 代理动态代理