1. #include <iostream>
  2. #include <unistd.h>
  3. #include <cstdlib>
  4. #include <arpa/inet.h>
  5. #include <sys/socket.h>
  6. #include <sys/wait.h>
  7. #include <signal.h>
  8. #include <string>
  9.  
  10. using namespace std;
  11.  
  12. const int BUFFER_SIZE = ;
  13.  
  14. void read_child_proc(int sig)
  15. {
  16. int status = ;
  17. waitpid(-, &status, WNOHANG);
  18. }
  19.  
  20. int deal_error(string error_msg)
  21. {
  22. cout << error_msg << endl;
  23. return ;
  24. }
  25.  
  26. int main()
  27. {
  28. // 创建套接字
  29. int ser_sock = socket(PF_INET, SOCK_STREAM, );
  30. if (ser_sock == -) {
  31. return deal_error("socket() failed");
  32. }
  33.  
  34. // 套接字绑定ip及端口号
  35. sockaddr_in ser_addr;
  36. ser_addr.sin_family = AF_INET;
  37. ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  38. ser_addr.sin_port = htons();
  39. if (bind(ser_sock, (sockaddr *)&ser_addr, sizeof(ser_addr)) == -) {
  40. close(ser_sock);
  41. return deal_error("bind() failed");
  42. }
  43.  
  44. // 开始监听
  45. if (listen(ser_sock, ) == -) {
  46. close(ser_sock);
  47. return deal_error("listen() failed");
  48. }
  49.  
  50. // 注册信号
  51. signal(SIGCHLD, read_child_proc); // 子进程执行结束信号注册,防止僵尸进程产生
  52. signal(SIGINT, exit); // CTRL+C信号注册,退出程序
  53.  
  54. while() {
  55. sockaddr_in clnt_addr;
  56. socklen_t addr_length = sizeof(clnt_addr);
  57. int clnt_sock = accept(ser_sock, (sockaddr *)&clnt_addr, &addr_length);
  58. if (clnt_sock == -) {
  59. continue;
  60. }
  61.  
  62. cout << "new client connected: " << clnt_sock << endl;
  63. pid_t pid = fork();
  64. if (pid < ) {
  65. continue;
  66. } else if (pid == ) { // 子进程
  67. close(ser_sock);
  68. char message[BUFFER_SIZE];
  69. int str_len = read(clnt_sock, message, BUFFER_SIZE-);
  70. if (str_len > ) {
  71. message[str_len] = '\0';
  72. cout << message << endl;
  73. }
  74. close(clnt_sock);
  75. sleep();
  76. return ;
  77. } else { // 父进程
  78. close(clnt_sock);
  79. }
  80. }
  81.  
  82. close(ser_sock);
  83. return ;
  84. }

C/C++网络编程9——多进程服务器端实现的更多相关文章

  1. C/C++网络编程7——多进程服务器端之fork函数

    通过前面几节的内容,我们已经可以实现基本的C/S结构的程序了,但是当多个客户端同时向服务器端请求服务时,服务器端只能按顺序一个一个的服务,这种情况下,客户端的用户是无法忍受的.所以虚实现并发的服务器端 ...

  2. C/C++网络编程8——多进程服务器端之销毁僵尸进程

    上一节提到,当子进程执行结束,父进程还在执行,在父进程结束之前子进程会成为僵尸进程,那么怎么销毁僵尸进程呢?父进程主动接收子进程的返回值. 销毁僵尸进程的方法: 1:使用wait函数 2:使用wait ...

  3. TCP/IP网络编程之多进程服务端(二)

    信号处理 本章接上一章TCP/IP网络编程之多进程服务端(一),在上一章中,我们介绍了进程的创建和销毁,以及如何销毁僵尸进程.前面我们讲过,waitpid是非阻塞等待子进程销毁的函数,但有一个不好的缺 ...

  4. 网络编程并发 多进程 进程池,互斥锁,信号量,IO模型

    进程:程序正在执行的过程,就是一个正在执行的任务,而负责执行任务的就是cpu 操作系统:操作系统就是一个协调.管理和控制计算机硬件资源和软件资源的控制程序. 操作系统的作用: 1:隐藏丑陋复杂的硬件接 ...

  5. TCP/IP网络编程之多进程服务端(一)

    进程概念及应用 我们知道,监听套接字会有一个等待队列,里面存放着不同客户端的连接请求,如果有一百个客户端,每个客户端的请求处理是0.5s,第一个客户端当然不会不满,但第一百个客户端就会有相当大的意见了 ...

  6. linux网络编程echo多进程服务器

    echo_server 多进程版本 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #incl ...

  7. day31 网络编程,多进程多线程

    今天的内容需要好好整理,概念性的东西比较多,都是需要理解的,这些是基层的理解,后期的很多知识都是要建立在今天的概念基础上的,以下两点是核心内容,必须要理解,自己把自己理解的注释加在里面: 进程就是程序 ...

  8. JAVA的网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  9. JAVA网络编程【转】出处不详

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

随机推荐

  1. shell脚本编程学习笔记(四)shell操作数据库

    一.数据库基本操作 1)登录mysql服务器:mysql -u root -p 密码 2)查看数据库:show databases 3)查看表:show tales from db; 4)查看表结构: ...

  2. .net C# Chart控件的简单使用

    1.拖控件Chart 到界面 2. 清除默认的序列  chart1.Series.Clear();   3.生成一个序列,并添加到chart1中,序列可添加多个  Series s1 = new Se ...

  3. python 中对list去重

    本文去重的前提是要保证顺序不变,本文给出了多种实现方法,需要的朋友可以参考下 1.直观方法 最简单的思路就是: ids = [1,2,3,3,4,2,3,4,5,6,1] news_ids = [] ...

  4. Django - 后台admin不显示带auto_now, auto_now_add选项的字段

    https://stackoverflow.com/questions/6386172/datetimefield-doesnt-show-in-admin-system 解决办法 class Rat ...

  5. C#面向对象三大特性:封装

    什么是封装 定义:把一个或多个项目封闭在一个物理的或者逻辑的包中.在面向对象程序设计方法论中,封装是为了防止对实现细节的访问. 封装的优点 1. 隔离性,安全性.被封装后的对象(这里的对象是泛指代码的 ...

  6. What Is A Airless Pump Bottle?

    What is an airless pump bottle?Unlike conventional dispensers that use a tube or suction tube to dra ...

  7. 关于websockets的压测工具

    这是在workerman群中得到的信息,记录在此: loadrunner  jemeter

  8. 【visio】 图片

    1.背景页设置 新建背景页:新建页面>设计>页面设置>页属性      使用背景页:在页属性页的"背景" 选项里,选择需要的背景. 2.插入图片 支持插入本地图片 ...

  9. flask 前端 分页 显示

    # flask 前端 分页 显示 1.分页原理 web查询大量数据并显示时有有三种方式: 从数据库中查询全部,在view/客户端筛选/分页:不能应对记录大多的情况,一般不使用: 分页查询,每次在数据库 ...

  10. Vue基础笔记2

    目录 1. 如何获取Vue对象中的成员? 2. pre指定 3. for循环 4. todolist 5. 分隔符 6. computed 计算后的 7. vue的生命周期(讲解不全) 8. watc ...