4高并发服务器:UDP局域网服务器(组播)

简介:  1 UDP局域网服务器 A读出每一个客户端发送过来的数据包,然后fork出子进程,由子进程去处理客户端请求。 B客户端与服务器段交换多个数据报,服务器为每一个客户端连接创建新的socket,在其上bind一个临时端口,然后用该socket处理对应客户端上的所有应答,这个办法要求在客户查看服务器第一个应答中的源端口号。然后后面利用此端口号和服务器进行交互。 2函


1 UDP局域网服务器

A读出每一个客户端发送过来的数据包,然后fork出子进程,由子进程去处理客户端请求。

B客户端与服务器段交换多个数据报,服务器为每一个客户端连接创建新的socket,在其上bind一个临时端口,然后用该socket处理对应客户端上的所有应答,这个办法要求在客户查看服务器第一个应答中的源端口号。然后后面利用此端口号和服务器进行交互。

2函数声明

int bind(int sockfd, const struct sockaddr*addr,socklen_t addrlen);

3依赖的头文件

#include<sys/types.h>

#include<sys/socket.h>

4函数说明:

addr中端口号为0,则使用临时端口号

注意:UDP是有可能出现接收缓冲区满,再接收数据时丢包。

A改变接收缓冲区大小

int n = 220 * 1024

setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,&n, sizeof(n));

B服务器应用层设计流量控制,控制发送数据速度。

5组播

组播组可以是永久的也可以是临时的,组播地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中的成员的数量都可以是任意的,甚至可以为零。那些没有保留下来的永久组播使用的ip组播地址,可以被临时组播组利用。

 

224.0.0.0224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;

224.0.1.0224.0.1.255是公用组播地址,可以用于Internet

224.0.2.0238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;

239.0.0.0239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。

 

ip ad查看网卡编号

man if_nametoindex,可以查看if_nametoindex的信息。

案例说明:

server.c

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <string.h>

#include <unistd.h>

#include <arpa/inet.h>

#include <net/if.h>

#define SERVER_PORT 8000

#define CLIENT_PORT 9000

#define MAXLINE 1500

 

#define GROUP "239.0.0.2"

 

int main(void)

{

   int sockfd, i ;

   struct sockaddr_in serveraddr, clientaddr;

   char buf[MAXLINE];

   char ipstr[INET_ADDRSTRLEN];        /* 16 Bytes */

   socklen_t clientlen;

   ssize_t len;

   struct ip_mreqn group;

   /* 构造用于UDP通信的套接字 */

   sockfd = socket(AF_INET, SOCK_DGRAM, 0);

 

   bzero(&serveraddr, sizeof(serveraddr));

   serveraddr.sin_family = AF_INET;    /* IPv4 */

   serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);     /* 本地任意IP INADDR_ANY = 0 */

   serveraddr.sin_port = htons(SERVER_PORT);

 

   bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

 

 

   /*设置组地址*/

   inet_pton(AF_INET, GROUP, &group.imr_multiaddr);

   /*本地任意IP*/

   inet_pton(AF_INET, "0.0.0.0", &group.imr_address);

   /* eth0 --> 编号   命令:ip ad */

   group.imr_ifindex = if_nametoindex("eth0");

 

   

   setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group));

 

   /*构造 client地址 IP+端口 */

   bzero(&clientaddr, sizeof(clientaddr));

   clientaddr.sin_family = AF_INET;    /* IPv4 */

   inet_pton(AF_INET, GROUP, &clientaddr.sin——ANY_addr.s_addr);

   clientaddr.sin_port = htons(CLIENT_PORT);

 

   while (1) {

       fgets(buf, sizeof(buf), stdin);

       sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));

   }

 

   close(sockfd);

   return 0;

}

client.c

#include <netinet/in.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>

#include <net/if.h>

 

#define SERVER_PORT 8000

#define MAXLINE 4096

 

#define CLIENT_PORT 9000

#define GROUP "239.0.0.2"

 

int main(int argc, char *argv[])

{

   struct sockaddr_in serveraddr, localaddr;

   int confd;

   ssize_t len;

   char buf[MAXLINE];

   /* 组播结构体 */

   struct ip_mreqn group;

 

   //1.创建一个socket

   confd = socket(AF_INET, SOCK_DGRAM, 0);

 

   //2.初始化本地端地址

   bzero(&localaddr, sizeof(localaddr));

   localaddr.sin_family = AF_INET;

   inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);

   localaddr.sin_port  = htons(CLIENT_PORT);

   bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr));

 

 

   /*设置组地址*/

   inet_pton(AF_INET, GROUP, &group.imr_multiaddr);

   /*本地任意IP*/

   inet_pton(AF_INET, "0.0.0.0", &group.imr_address);

   /* eth0 --> 编号   命令:ip ad */

   group.imr_ifindex = if_nametoindex("eth0");

 

   /*设置client加入多播组 */

   setsockopt(confd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));

 

   while (1) {

       len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);

       write(STDOUT_FILENO, buf, len);

   }

 

   close(confd);

   return 0;

}

 

 

目录
相关文章
|
15天前
|
网络协议 Java API
【JavaEE】——Udp翻译器的实现(回显服务器)
网络编程,DatagramSocket 和 DatagramPacket类,回显服务器,服务器实现,客户端实现,
|
3月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
70 3
|
3月前
|
存储 网络协议 Java
【网络】UDP回显服务器和客户端的构造,以及连接流程
【网络】UDP回显服务器和客户端的构造,以及连接流程
70 2
|
3月前
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
84 1
|
6月前
|
网络协议 网络架构
【网络编程入门】TCP与UDP通信实战:从零构建服务器与客户端对话(附简易源码,新手友好!)
在了解他们之前我们首先要知道网络模型,它分为两种,一种是OSI,一种是TCP/IP,当然他们的模型图是不同的,如下
238 1
|
6月前
|
Web App开发
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
|
9天前
|
机器学习/深度学习 人工智能 PyTorch
阿里云GPU云服务器怎么样?产品优势、应用场景介绍与最新活动价格参考
阿里云GPU云服务器怎么样?阿里云GPU结合了GPU计算力与CPU计算力,主要应用于于深度学习、科学计算、图形可视化、视频处理多种应用场景,本文为您详细介绍阿里云GPU云服务器产品优势、应用场景以及最新活动价格。
阿里云GPU云服务器怎么样?产品优势、应用场景介绍与最新活动价格参考
|
8天前
|
存储 运维 安全
阿里云弹性裸金属服务器是什么?产品规格及适用场景介绍
阿里云服务器ECS包括众多产品,其中弹性裸金属服务器(ECS Bare Metal Server)是一种可弹性伸缩的高性能计算服务,计算性能与传统物理机无差别,具有安全物理隔离的特点。分钟级的交付周期将提供给您实时的业务响应能力,助力您的核心业务飞速成长。本文为大家详细介绍弹性裸金属服务器的特点、优势以及与云服务器的对比等内容。
|
16天前
|
人工智能 JSON Linux
利用阿里云GPU加速服务器实现pdf转换为markdown格式
随着AI模型的发展,GPU需求日益增长,尤其是个人学习和研究。直接购置硬件成本高且更新快,建议选择阿里云等提供的GPU加速型服务器。
利用阿里云GPU加速服务器实现pdf转换为markdown格式
|
3天前
|
机器学习/深度学习 弹性计算 缓存
简单聊聊,阿里云2核2G3M带宽云服务器与轻量应用服务器区别及选择参考
2核2G3M带宽云服务器与轻量应用服务器是目前阿里云的活动中,入门级走量型云服务器,轻量云服务器2核2G3M带宽68元一年,经济型e实例云服务器2核2G3M带宽99元1年。同样的配置,对于有的新手用户来说,有必要了解一下他们之间的区别,以及各自的购买和续费相关政策,从而选择更适合自己需求的云服务器。本文为大家简单分析一下我们应该选择哪一款。