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]; socklen_t clientlen; ssize_t len; struct ip_mreqn group; /* sockfd = socket(AF_INET, SOCK_DGRAM, 0); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 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 --> group.imr_ifindex = if_nametoindex("eth0"); setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group)); /*构造 client地址 bzero(&clientaddr, sizeof(clientaddr)); clientaddr.sin_family = AF_INET; 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 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 --> 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; } |