一、迭代与并发服务器概述

服务器设计技术有很多,按使用的协议来分有 TCP 服务器和 UDP 服务器,按处理方式来分有迭代服务器(循环服务器)和并发服务器。

在网络程序里面,一般来说都是许多客户对应一个服务器(多对一),为了处理客户的请求,对服务端的程序就提出了特殊的要求。

目前最常用的服务器模型有:

迭代服务器:服务器在同一时刻只能响应一个客户端的请求

并发服务器:服务器在同一时刻可以响应多个客户端的请求

二、UDP 迭代服务器

UDP 循环服务器每次从套接字上读取一个客户端的请求 -> 处理 -> 然后将结果返回给客户机。

因为 UDP 是非面向连接的,没有一个客户端可以老是占住服务端。只要处理过程不是死循环,或者耗时不是很长,服务器对于每一个客户机的请求在某种程度上来说是能够满足。

udp迭代服务器框架:

[csharp] view plaincopy
  1. //1.创建套接字
  2. int sockfd = socket(...);
  3. //2.绑定套接字
  4. bind(...);
  5. while(1)
  6. {
  7. //3.接收客户端的请求
  8. recvfrom(...);
  9. //4.处理客户端的请求
  10. process(...);
  11. //5.反馈处理结果
  12. sendto(...);
  13. }

udp迭代服务器参考代码:

[csharp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. int main(int argc, char *argv[])
  9. {
  10. unsigned short port = 8080; //本地端口
  11. //1.创建udp套接字
  12. int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  13. if(sockfd < 0)
  14. {
  15. perror("socket");
  16. exit(-1);
  17. }
  18. // 配置本地网络信息
  19. struct sockaddr_in my_addr;
  20. bzero(&my_addr, sizeof(my_addr));   // 清空
  21. my_addr.sin_family = AF_INET;       // IPv4
  22. my_addr.sin_port   = htons(port);   // 端口
  23. my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip
  24. printf("Binding server to port %d\n", port);
  25. // 2.绑定套接字
  26. int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
  27. if(err_log != 0)
  28. {
  29. perror("bind");
  30. close(sockfd);
  31. exit(-1);
  32. }
  33. printf("receive data...\n");
  34. while(1)
  35. {
  36. int recv_len;
  37. char recv_buf[512] = {0};
  38. struct sockaddr_in client_addr;
  39. char cli_ip[INET_ADDRSTRLEN] = "";//INET_ADDRSTRLEN=16
  40. socklen_t cliaddr_len = sizeof(client_addr);
  41. //3.接收客户端的请求
  42. recv_len = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr*)&client_addr, &cliaddr_len);
  43. //4.处理客户端的请求,这里只是把接收过来的数据打印
  44. inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
  45. printf("\nip:%s ,port:%d\n",cli_ip, ntohs(client_addr.sin_port)); // 客户端的ip
  46. printf("data(%d):%s\n",recv_len,recv_buf);  // 客户端的数据
  47. //5.反馈处理结果,这里把接收直接到客户端的数据回复过去
  48. sendto(sockfd, recv_buf, recv_len, 0, (struct sockaddr*)&client_addr, cliaddr_len);
  49. }
  50. close(sockfd);
  51. return 0;
  52. }

运行结果:

三、tcp迭代服务器

TCP 迭代服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接。TCP 迭代服务器一次只能处理一个客户端的请求,只有在这个客户的所有请求满足后,服务器才可以继续后面的请求。如果有一个客户端占住服务器不放时,其它的客户机都不能工作了,因此,TCP 服务器一般很少用迭代服务器模型的。

tcp迭代服务器框架:

[csharp] view plaincopy
  1. //1.创建tcp套接字
  2. int sockfd = socket(...);
  3. //2.绑定套接字
  4. bind(...);
  5. //3.监听套接字
  6. listen(...);
  7. while(1)
  8. {
  9. //4.提取已连接套接字
  10. int connfd = accept(...);
  11. //5.处理客户端的请求
  12. process(...);
  13. //6.关闭已连接套接字
  14. close(connfd);
  15. }
  16. //7.关闭监听套接字
  17. close(sockfd);

tcp迭代服务器参考代码:

[csharp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. int main(int argc, char *argv[])
  9. {
  10. unsigned short port = 8080;     // 本地端口
  11. //1.创建tcp套接字
  12. int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  13. if(sockfd < 0)
  14. {
  15. perror("socket");
  16. exit(-1);
  17. }
  18. //配置本地网络信息
  19. struct sockaddr_in my_addr;
  20. bzero(&my_addr, sizeof(my_addr));     // 清空
  21. my_addr.sin_family = AF_INET;         // IPv4
  22. my_addr.sin_port   = htons(port);     // 端口
  23. my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ip
  24. //2.绑定
  25. int err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr));
  26. if( err_log != 0)
  27. {
  28. perror("binding");
  29. close(sockfd);
  30. exit(-1);
  31. }
  32. //3.监听,套接字变被动
  33. err_log = listen(sockfd, 10);
  34. if(err_log != 0)
  35. {
  36. perror("listen");
  37. close(sockfd);
  38. exit(-1);
  39. }
  40. printf("listen client @port=%d...\n",port);
  41. while(1)
  42. {
  43. struct sockaddr_in client_addr;
  44. char cli_ip[INET_ADDRSTRLEN] = "";
  45. socklen_t cliaddr_len = sizeof(client_addr);
  46. //4.取出客户端已完成的连接
  47. int connfd;
  48. connfd = accept(sockfd, (struct sockaddr*)&client_addr, &cliaddr_len);
  49. if(connfd < 0)
  50. {
  51. perror("accept");
  52. continue;
  53. }
  54. //5.打印客户端的ip和端口
  55. inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
  56. printf("----------------------------------------------\n");
  57. printf("client ip=%s,port=%d\n", cli_ip,ntohs(client_addr.sin_port));
  58. // 接收数据
  59. char recv_buf[512] = {0};
  60. int len =  recv(connfd, recv_buf, sizeof(recv_buf), 0);
  61. // 处理数据,这里只是打印接收到的内容
  62. printf("\nrecv data:\n");
  63. printf("%s\n",recv_buf);
  64. // 反馈结果
  65. send(connfd, recv_buf, len, 0);
  66. //6.关闭已连接套接字
  67. close(connfd);
  68. printf("client closed!\n");
  69. }
  70. //7.关闭监听套接字
  71. close(sockfd);
  72. return 0;
  73. }

运行结果:

Linux网络编程——tcp、udp迭代服务器相关推荐

  1. 【Linux网络编程】UDP 套接字编程

    [Linux网络编程]UDP 套接字编程 [1]用户数据报协议(UDP) UDP是一个简单的传输层协议,不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数 ...

  2. Linux网络编程——tcp并发服务器(poll实现)

    https://blog.csdn.net/lianghe_work/article/details/46535859 想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程--I/ ...

  3. 网络编程---TCP/UDP套接字编程原理

    本篇介绍的是Linux下的网络编程,故有些接口是不适用于Windows的,但是具体概念和实现方法是大体一致的 本篇重在讲解原理,具体实现请戳这里->UDP套接字编程实现 介绍 网络编程套接字(s ...

  4. Linux 网络编程 TCP

    (一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端         网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客 ...

  5. 网络编程(Tcp/Udp实现聊天、文件上传)

    网络编程 1.1 概述 计算机网络是指将位置不同的多台[计算机 通过通信线路连接起来,实现资源共享和信息传递的计算机系统 1.2 网络通信的要素 ip和端口 网络通信协议(tcp/udp) 1.3 I ...

  6. linux网络编程tcp和udp基本函数调用过程及如何选择

    1. socket编程 1.1 概述 TCP是TCP/IP体系中面向连接的传输层协议,它提供全双工和可靠交付的服务.它采用许多机制来确保端到端结点之间的可靠数据传输,如采用序列号.确认重传.滑动窗口等 ...

  7. Linux网络编程——tcp并发服务器(多进程)

    https://blog.csdn.net/lianghe_work/article/details/46503895 一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多 ...

  8. Linux网络编程——tcp并发服务器(epoll实现)

    https://blog.csdn.net/lianghe_work/article/details/46551871 通过epoll实现tcp并发回执服务器(客户端给服务器发啥,服务器就给客户端回啥 ...

  9. Linux网络编程——tcp并发服务器(多线程)

    https://blog.csdn.net/lianghe_work/article/details/46504243 tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创 ...

  10. [windows网络编程]tcp/udp编程初步详解-转

    #pragma comment (lib,"ws2_32.lib") #include <Winsock2.h> #include <stdio.h> 如你 ...

最新文章

  1. 搜索引擎:文本分类——TF/IDF算法
  2. Android之给图片添加涂鸦(文字)
  3. 计算机外观类型,知道你的笔记本电脑是什么类型的吗?五大类型派对号入座
  4. getDeclaredField和getField的区别
  5. 资源放送丨《Oracle中为什么没有Double Write?Oracle支持原子写吗?》PPT视频
  6. Java并发编程之CAS和AQS
  7. c#中空数组_C# 如何判断数组是否拥有空元素呢?
  8. 基于better-scroll实现的类似ios选择器
  9. jracdrive变频器说明书580_ABB变频器ACS580说明书.pdf
  10. pyqt5 yolov4实现车牌识别系统
  11. MapperReduce初学附加自定义输出的NameWordCount统计
  12. Android 客户端上开发人人客户端系列教程
  13. Pyrhon pyqt5 视频转字符画
  14. 智能眼镜现在是什么水平?
  15. 圣思园张龙-Java SE 第三讲(原生数据类型使用陷阱 Pitfall of Primitive Data Type)
  16. 呼叫中心-自动外呼接口设置
  17. C语言中的这些经典题目你都会了吗?【一文带你回顾经典】【全程高能】
  18. 抓包技术(浏览器APP小程序PC应用)
  19. 由“三姬分金”到“海盗分金”
  20. 数据库(oracle)服务器的cpu大于80%

热门文章

  1. HTML5 — 知识篇总结《I》【入门知识】
  2. Android RadioButton(单选按钮)点击事件的两种方法
  3. Vue学习手记02-路由创建
  4. 查看网络情况netstat指令与动态监控top指令
  5. Nginx负载均衡与反向代理——基础功能
  6. 用Pylint规范化Python代码,附PyCharm配置
  7. 201521123115 《Java程序设计》第3周学习总结
  8. SharePoint 2010 获取列表全部定义方法
  9. 执行力 - 快速反应
  10. 控制台应用程序《石头剪刀布》——新手,