首页 > 其他分享 >fork前后创建socket对 udp server的影响

fork前后创建socket对 udp server的影响

时间:2024-09-06 11:14:48浏览次数:10  
标签:fork udp socket int client fd include recv addr

结论:

Linux上五元组关系由socket 维护的(但是mac 和linux 表现还不一样)

代码:

udp-client.c

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#define DEST_PORT 8080
#define DSET_IP_ADDRESS  "127.0.0.1"


int do_main()
{
  /* socket文件描述符 */
  int sock_fd;

  /* 建立udp socket */
  sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
  if(sock_fd < 0)
  {
    perror("socket");
    exit(1);
  }

  /* 设置address */
  struct sockaddr_in addr_serv;
  int len;
  memset(&addr_serv, 0, sizeof(addr_serv));
  addr_serv.sin_family = AF_INET;
  addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
  addr_serv.sin_port = htons(DEST_PORT);
  len = sizeof(addr_serv);


  int send_num;
  int recv_num;
  char send_buf[20] = "hey, who are you?";
  char recv_buf[20];
  while (1) {
    printf("client send: %s\n", send_buf);

    send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);

    if(send_num < 0)
    {
      perror("sendto error:");
      exit(1);
    }
    sleep(1);
  }
  recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);

  if(recv_num < 0)
  {
    perror("recvfrom error:");
    exit(1);
  }

  recv_buf[recv_num] = '\0';
  printf("client receive %d bytes: %s\n", recv_num, recv_buf);

  close(sock_fd);

  return 0;
}
int main() {
  for (int i =0; i < 4; i++) {
    if (fork() == 0) { // 子进程  
        do_main();  
        exit(EXIT_SUCCESS); // 子进程处理完请求后退出  
    }  
  }
  // 父进程等待子进程结束(可选)  
  while (waitpid(-1, NULL, 0) > 0); 
  return 0;
}

udp-server.c

#include <iostream>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <cstdlib>  
#include <sys/types.h>  
#include <sys/wait.h>  
#include <arpa/inet.h>
#define PORT 8080  
#define BUF_SIZE 1024  
  
void handle_client(int server_fd) { 
  while(1){ 
    char buffer[BUF_SIZE];  
    struct sockaddr_in client_addr;  
    socklen_t client_len = sizeof(client_addr);  
  
    int n = recvfrom(server_fd, buffer, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &client_len);  
    if (n < 0) {  
        perror("recvfrom");  
        exit(1);  
    }  
  
    std::cout << "Received from " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port)  
              << " in process " << getpid() << std::endl;  
    // 可以选择发送响应给客户端  
    // sendto(server_fd, buffer, n, 0, (struct sockaddr*)&client_addr, client_len);  
    }
}  
  
int main() {  
    int server_fd, new_socket;  
    struct sockaddr_in address;  
    int opt = 1;  
    int addrlen = sizeof(address);  
  
    if ((server_fd = socket(AF_INET, SOCK_DGRAM, 0)) == 0) {  
        perror("socket failed");  
        exit(EXIT_FAILURE);  
    }  
  
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) {  
        perror("setsockopt (SO_REUSEPORT) failed");  
        exit(EXIT_FAILURE);  
    }  
  
    address.sin_family = AF_INET;  
    address.sin_addr.s_addr = INADDR_ANY;  
    address.sin_port = htons(PORT);  
  
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {  
        perror("bind failed");  
        exit(EXIT_FAILURE);  
    }  
  
    // 创建多个进程来处理客户端请求  
    for (int i = 0; i < 4; ++i) { // 假设我们创建5个进程  
        if (fork() == 0) { // 子进程  
            handle_client(server_fd);  
            exit(EXIT_SUCCESS); // 子进程处理完请求后退出  
        }  
    }  
  
    // 父进程等待子进程结束(可选)  
    while (waitpid(-1, NULL, 0) > 0);  
  
    close(server_fd);  
    return 0;  
}

 

udp-server2.c

#include <iostream>  
#include <sys/socket.h>  
#include <netinet/in.h>  
#include <string.h>  
#include <unistd.h>  
#include <fcntl.h>  
#include <cstdlib>  
#include <sys/types.h>  
#include <sys/wait.h>  
#include <arpa/inet.h>
#define PORT 8080  
#define BUF_SIZE 1024  
  
void handle_client(int server_fd) { 
  while(1){ 
    char buffer[BUF_SIZE];  
    struct sockaddr_in client_addr;  
    socklen_t client_len = sizeof(client_addr);  
    std::cout << "ready recv:" << getpid() << std::endl;
    int n = recvfrom(server_fd, buffer, BUF_SIZE, 0, (struct sockaddr*)&client_addr, &client_len);  
    if (n < 0) {  
        perror("recvfrom");  
        exit(1);  
    }  
  
    std::cout << "Received from " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port)  
              << " in process " << getpid() << std::endl;  
    // 可以选择发送响应给客户端  
    // sendto(server_fd, buffer, n, 0, (struct sockaddr*)&client_addr, client_len);  
    }
}  
  
int do_main() {  
    int server_fd, new_socket;  
    struct sockaddr_in address;  
    int opt = 1;  
    int addrlen = sizeof(address);  
  
    if ((server_fd = socket(AF_INET, SOCK_DGRAM, 0)) == 0) {  
        perror("socket failed");  
        exit(EXIT_FAILURE);  
    }  
  
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) {  
        perror("setsockopt (SO_REUSEPORT) failed");  
        exit(EXIT_FAILURE);  
    }  
  
    address.sin_family = AF_INET;  
    address.sin_addr.s_addr = INADDR_ANY;  
    address.sin_port = htons(PORT);  
  
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {  
        perror("bind failed");  
        exit(EXIT_FAILURE);  
    }  
    handle_client(server_fd);
    // // 创建多个进程来处理客户端请求  
    // for (int i = 0; i < 4; ++i) { // 假设我们创建5个进程  
    //     if (fork() == 0) { // 子进程  
    //         handle_client(server_fd);  
    //         exit(EXIT_SUCCESS); // 子进程处理完请求后退出  
    //     }  
    // }  
  
    // 父进程等待子进程结束(可选)  
    // while (waitpid(-1, NULL, 0) > 0);  
  
    close(server_fd);  
    return 0;  
}

int main() {
  for (int i =0; i < 4; i++) {
    if (fork() == 0) { // 子进程  
        do_main();  
        exit(EXIT_SUCCESS); // 子进程处理完请求后退出  
    }  
  }
  // 父进程等待子进程结束(可选)  
  while (waitpid(-1, NULL, 0) > 0); 
  return 0;
}

 

  

过程:

 

结果:

 

 

标签:fork,udp,socket,int,client,fd,include,recv,addr
From: https://www.cnblogs.com/micoblog/p/18399867

相关文章

  • node通过ffmpeg将多路rtsp、rtmp流媒体转换为多端口websocket流供前端播放
    node通过ffmpeg将多路rtsp、rtmp流媒体转换为多端口websocket流供前端播放这里写目录标题node通过ffmpeg将多路rtsp、rtmp流媒体转换为多端口websocket流供前端播放1安装node2安装ffmpeg3【重要】使用node搭建rtsp、rtmp转码服务器(必须要提前安装ffmpeg)4前端(vue3)播......
  • java.lang.ClassNotFoundException: net.logstash.logback.appender.LogstashTcpSocke
    出现以下错误,是因为项目缺少依赖:atorg.springframework.boot.logging.logback.LogbackLoggingSystem.reportConfigurationErrorsIfNecessary(LogbackLoggingSystem.java:189)atorg.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(Log......
  • 【git】fork远程仓库,fork仓库同步和提交pull request
    一、fork远程仓库,将会在你的GitHub账号中创建一个副本1.找到你想要的github仓库,点击Fork按钮 2.选择相应的Owner和想要clone的上游原始仓库的reponame,点击Createfork 3.fork创建成功(大概几秒钟就好了) 二、fork仓库同步上游仓库1.将上游仓库添加位远程仓库,并命......
  • 网络编程day01(IP地址、Socket、端口号)
    目录【1】IP地址1》基本概念IP地址 NAT设备(网络地址转换)DHCP服务器(动态主机配置协议)2》网络号/主机号(二级划分) 3》IP地址分类 特殊地址4》子网掩码5》三级划分【2】socket1》socket发展2》socket介绍3》为什么需要socket?4》socket类型【3】端口号 【1】......
  • 使用AI写WebSocket知识是一种怎么样的体验?
    一、WebSocket基础知识1.WebSocket概念1.1为什么会出现WebSocket一般的Http请求我们只有主动去请求接口,才能获取到服务器的数据。例如前后端分离的开发场景,自嘲为切图仔的前端大佬找你要一个配置信息的接口,我们后端开发三下两下开发出一个RESTful架构风格的API接口,只有当......
  • 【python】socket 入门以及多线程tcp链接
    Socket入门及多线程tcp链接网络基础知识三要素Socket是套接字的意思,是网络编程的核心对象,通信两端都独有自己的Socket对象,数据在两个Socket之间通过字节流(TCP协议)或者数据报包(UDP协议)的形式进行传输.本文主要针对tcp流程进行讲解socket-tcp流程图1.创建......
  • 实现TCP收发信息和UDP收发信息
    1.TCP通信服务器端#include<myhead.h>#defineSERPORT6666#defineSERIP"192.168.0.136"#defineBACKLOG5intmain(intargc,constchar*argv[]){ intoldfd=socket(AF_INET,SOCK_STREAM,0); if(oldfd==-1) { perror("socket"); retu......
  • java 使用WebSocket 功能实现
    java使用WebSocket功能实现我整理的一些关于【架构设计】的项目学习资料+视频(附讲解~~)和大家一起分享、学习一下: https://d.51cto.com/bLN8S1实现Java直播弹幕功能1.引言本文将教会一位刚入行的小白如何实现Java直播弹幕功能。直播弹幕是指在直播过程中,观众可以发送实时弹幕......
  • C# WebSocket高并发通信阻塞问题
    项目上遇到使用WebSocket超时问题,具体情况是这样的,OTA升级过程中,解压zip文件会有解压进度事件,将解压进度通过进程通信传给另一进程,通信提示超时异常小伙伴堂园发现大文件使用Zip解压,解压进度事件间隔竟然是1ms,简直超大频率啊但是,解压事件超频也不应该通信异常啊,于是我通过1ms定......
  • 【网络原理】Udp 的报文结构,保姆式教学,快速入门
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......