广播
1.广播地址
如果用{netid, subnetid, hostid}( {网络ID,子网ID,主机ID})表示IPv4地址。那么有四种类型的广播地址,我们用-1表示所有比特位均为1的字段:
1). 子网广播地址:{netid, subnetid, -1}。这类地址编排指定子网上的所有接口。
2). 全部子网广播地址:{netid, -1, -1}。这类广播地址编排指定网络上的所有子网。
3). 网络广播地址:{netid, -1}。这类地址用于不进行子网划分的网络。
4). 受限广播地址:{-1, -1, -1}。路由器从不转发目的地址为255.255.255.255的IP数据
2.单播和广播的比较
单播IP数据报仅有通过目的IP地址指定的单个主机接受,子网上的其他主机均不受影响;
子网上所有未参加相应广播应用的所有机也必须沿协议栈一路向上完整的处理收取UDP广播数据报,直至该数据包经历UDP层时被丢弃为止
3.竞争状态
多个进程访问共享数据,但正确结构依赖于进程的执行顺序,这种情况我们称之为竞争状态(race condition)。竞争状态通常是线程编程中始终要注意的一个重要问题,因为在线程中有非常之多的数据需要共享,例如所有的全程变量。
在进行信号处理时,通常会出现各种类型的竞争状态。这是因为在我们的程序执行过程中,内核随时都会递交信号。
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 <net/if.h> #include <fcntl.h> #include <unistd.h> #include <ctype.h> #define SERVER_PORT 5555 #define CLIENT_PORT 5556 #define MAXLINE 4096 int main(int argc,char *argv[]) { struct sockaddr_in localaddr; int confd; ssize_t len; char buf[MAXLINE]; //1.创建一个socket confd=socket(AF_INET,SOCK_DGRAM,0); bzero(&localaddr,sizeof(localaddr)); localaddr.sin_family=AF_INET; localaddr.sin_addr.s_addr=htonl(INADDR_BROADCAST); localaddr.sin_port =htons(SERVER_PORT); int opt=-1; setsockopt(confd,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt)); int clientlen=sizeof(struct sockaddr_in); while(1){ fgets(buf,sizeof(buf),stdin); sendto(confd,buf,strlen(buf),0,(struct sockaddr*)&localaddr,clientlen); len=recvfrom(confd,buf,sizeof(buf),0,NULL,0); write(STDIN_FILENO,buf,len); } close(confd); return 0; }
server.c
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <netinet/in.h> #include <ctype.h> #include <net/if.h> #define SERVER_PORT 5555 #define CLIENT_PORT 5556 #define MAXLINE 1024 int main(void) { int sockfd,i; ssize_t len; struct sockaddr_in serveraddr,clientaddr; char buf[MAXLINE]; char ipstr[INET_ADDRSTRLEN];//16个字节 socklen_t clientlen; //构造用于UDP通信的套接字 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); //printf("%x ",INADDR_ANY); int opt=-1; setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt)); bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr)); /*构造client地址 */ bzero(&clientaddr,sizeof(clientaddr)); clientaddr.sin_family=AF_INET; clientaddr.sin_addr.s_addr=htonl(INADDR_ANY); clientaddr.sin_port=htons(SERVER_PORT); clientlen=sizeof(struct sockaddr_in); while(1){ memset(buf,0,sizeof(buf)); len=recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&clientlen); printf("Rec from client--IP: %s PORT %d ", inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr)), ntohs(clientaddr.sin_port)); i=0; while(i<len){ buf[i]=toupper(buf[i]); i++; } buf[i]='