4高并发服务器:UDP局域网服务器(组播)
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.0~224.0.0.255為預留的組播地址(永久組地址),地址224.0.0.0保留不做分配,其它地址供路由協議使用;
224.0.1.0~224.0.1.255是公用組播地址,可以用于Internet;
224.0.2.0~238.255.255.255為用戶可用的組播地址(臨時組地址),全網范圍內有效;
239.0.0.0~239.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; } |
?
?
總結
以上是生活随笔為你收集整理的4高并发服务器:UDP局域网服务器(组播)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 雅马哈电动车怎么解除限制马力?
- 下一篇: 11R和12R的轮胎转100公里差多少?