您的位置:首页 > 汽车 > 时评 > 六安网站制作哪里有_网络公司经营范围可以加技_seo 推广怎么做_网络推广策划方案模板

六安网站制作哪里有_网络公司经营范围可以加技_seo 推广怎么做_网络推广策划方案模板

2025/1/11 19:45:51 来源:https://blog.csdn.net/wh_xia_jun/article/details/144355491  浏览:    关键词:六安网站制作哪里有_网络公司经营范围可以加技_seo 推广怎么做_网络推广策划方案模板
六安网站制作哪里有_网络公司经营范围可以加技_seo 推广怎么做_网络推广策划方案模板

socket通讯服务器模型.有多种类型,多进程只是其中比较少用的一种,原因是它太“重”。

在生产环境中,使用多进程模型可能不是最高效的选择,特别是在处理大量并发连接时。多线程模型或IO多路复用模型可能是更好的选择。

父子进程:

多进程并发服务器原型 

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main() {pid_t pid;// 创建子进程pid = fork();if (pid < 0) {  // 创建子进程失败fprintf(stderr, "Fork failed.\n");return 1;} else if (pid == 0) {  // 子进程printf("Hello from child process!\n");} else {  // 父进程printf("Hello from parent process!\n");}return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>  // 正确的头文件
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#include <string.h>  // 为了使用 strerror#define N 64// 回收进程的资源
void handler(int signum)
{wait(NULL);
}int main(int argc, char const *argv[])
{int sockfd;if (argc < 3){printf("usage: %s <ip> <port>\n", argv[0]);return -1;}sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket err");return -1;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(atoi(argv[2]));// 自动绑定所有的本机网卡的地址addr.sin_addr.s_addr = INADDR_ANY;  // 或者使用 inet_addr(argv[1]) 来绑定特定 IPint addrlen = sizeof(addr);if (bind(sockfd, (struct sockaddr *)&addr, addrlen) < 0){perror("bind err");close(sockfd);return -1;}if (listen(sockfd, 5) < 0){perror("listen err");close(sockfd);return -1;}printf("wait client connect\n");int clifd;struct sockaddr_in cliaddr;struct sigaction sa;memset(&sa, 0, sizeof(sa));sa.sa_handler = handler;sigaction(SIGCHLD, &sa, NULL);while (1){clifd = accept(sockfd, (struct sockaddr *)&cliaddr, &addrlen);if (clifd < 0){perror("accept err");continue;}pid_t pid = fork();if (pid < 0){perror("fork err");close(clifd);continue;}else if (pid == 0)  // 子进程{int ret;char buf[N] = {0};while (1){ret = recv(clifd, buf, N, 0);if (ret < 0){perror("recv err");continue;}else if (ret == 0){printf("peer exit\n");break;}else{printf("ip = %s, port = %d, data = %s\n",inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buf);}}close(clifd);exit(0);}else  // 父进程{close(clifd);  // 关闭子进程已使用的套接字描述符}}close(sockfd);  // 这行代码实际上不会被执行,因为上面的循环是无限循环return 0;
}

这段代码实现了一个简单的多进程服务器,它能够监听来自客户端的连接请求,并在接受到连接后,通过创建一个新的子进程来处理每个客户端的通信。

包含的头文件

  • stdio.h:用于基本的输入输出函数,如printf
  • sys/types.hsys/socket.hnetinet/in.harpa/inet.h:这些头文件提供了网络编程所需的类型和函数,包括套接字创建、地址转换等。
  • unistd.h:提供对POSIX操作系统API的访问,如closeforkexit等。
  • stdlib.h:包含了一些常用的库函数,如atoi(字符串转整数)。
  • sys/stat.hfcntl.h:虽然在这段代码中没有直接使用,但通常用于文件操作。
  • signal.h:提供了信号处理的功能。
  • sys/wait.h:提供了等待进程结束的功能。
  • string.h:提供了字符串处理的函数,如memsetstrerror(尽管strerror在这段代码中未使用)。

宏定义

  • #define N 64:定义了缓冲区的大小为64字节。

函数

  • handler(int signum):这是一个信号处理函数,用于处理子进程结束的信号(SIGCHLD)。它调用wait(NULL)来回收结束的子进程的资源。

主函数 main

  1. 参数检查:程序需要两个参数:IP地址和端口号。如果参数不足,程序将打印用法信息并退出。

  2. 创建套接字:使用socket函数创建一个TCP套接字。

  3. 配置地址结构:将服务器的IP地址(错误地设置为INADDR_ANY,这通常用于绑定到所有可用接口,应该使用inet_addr(argv[1])来指定特定IP)和端口号配置到sockaddr_in结构中。

  4. 绑定套接字:使用bind函数将套接字与指定的IP地址和端口号绑定。

  5. 监听连接:使用listen函数使套接字进入监听状态,准备接受连接请求。

  6. 设置信号处理:使用sigaction函数设置SIGCHLD信号的处理函数为handler

  7. 接受连接:在一个无限循环中,使用accept函数接受来自客户端的连接请求。每当接受到一个连接时,都会创建一个新的子进程来处理这个连接。

  8. 子进程处理

    • 在子进程中,使用recv函数从客户端接收数据。
    • 打印接收到的数据以及客户端的IP地址和端口号。
    • 当客户端关闭连接(recv返回0)时,子进程也关闭套接字并退出。
  9. 父进程处理

    • 父进程在创建子进程后关闭子进程使用的套接字描述符(clifd),因为子进程已经有自己的描述符副本。
    • 父进程继续监听新的连接请求。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com