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;

}

 

 

目录
相关文章
|
12月前
|
网络协议 Java API
【JavaEE】——Udp翻译器的实现(回显服务器)
网络编程,DatagramSocket 和 DatagramPacket类,回显服务器,服务器实现,客户端实现,
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
202 3
|
存储 网络协议 Java
【网络】UDP回显服务器和客户端的构造,以及连接流程
【网络】UDP回显服务器和客户端的构造,以及连接流程
263 3
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
180 1
|
网络协议 网络架构
【网络编程入门】TCP与UDP通信实战:从零构建服务器与客户端对话(附简易源码,新手友好!)
在了解他们之前我们首先要知道网络模型,它分为两种,一种是OSI,一种是TCP/IP,当然他们的模型图是不同的,如下
469 1
|
Web App开发
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
|
3月前
|
网络协议 安全 网络安全
什么是TCP/UDP/HTTP?它们如何影响你的内网穿透体验?
数据的传输离不开各种协议,它们就像现实世界中的交通规则,规定了数据如何打包、寻址、传输和接收。对于使用内网穿透的用户来说,理解TCP、UDP和HTTP这些基础协议的特点,能帮助你更好地理解其性能表现,并选择最适合的配置方案。
|
5月前
|
网络协议 安全 网络安全
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
详细阐述 TCP、UDP、ICMPv4 和 ICMPv6 协议-以及防火墙端口原理优雅草卓伊凡
438 2
|
8月前
|
网络协议 Java 开发工具
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
全平台开源即时通讯IM框架MobileIMSDK:7端+TCP/UDP/WebSocket协议,鸿蒙NEXT端已发布,5.7K Stars
453 1
|
12月前
|
监控 网络协议 网络性能优化
不再困惑!一文搞懂TCP与UDP的所有区别
本文介绍网络基础中TCP与UDP的区别及其应用场景。TCP是面向连接、可靠传输的协议,适用于HTTP、FTP等需要保证数据完整性的场景;UDP是无连接、不可靠但速度快的协议,适合DNS、RIP等对实时性要求高的应用。文章通过对比两者在连接方式、可靠性、速度、流量控制和数据包大小等方面的差异,帮助读者理解其各自特点与适用场景。

热门文章

最新文章