TCP/IP网络编程 学习笔记

前言:想想这么一种情况,网络电台可能需要同时向成千上万的用户传输相同的数据,如果用我们以前讲过的传输形式,每个用户都传输一次,这样肯定是不合理的。因此,就引入了多播技术来解决这个问题,它可以同时向大量用户发送相同数据。其基本原理是这样的:有个多播组,只要加入这个组里的所有客服端,服务端发送的数据它们都能收到,,具体传输到多播组里的每个客户是由路由完成的(如果路由器不支持多播或网络堵塞,实现多播也会使用隧道技术)。

多播

多播的数据传输特点如下: 1,多播服务器端针对特定多播组,只需发送1次数据,该组内的所有所有客服端都能接收数据。 2,多播组数可在IP地址范围内任意增加。

设置生存时间和加入多播组的方法 1,设置生存时间:只指服务端发送的数据包最远能传递的距离,用整数表示,并且每经过1个路由器就减1,当为0时,该数据包无法再被传递,只能销毁。因此,这个值设置过大将影响网络流量。当然,设置过小也会无法传递到目标(通过套接字可选项设置,示例代码中有使用方法)。

2,加入多播组:也是通过套接字可选项设置,示例代码中有使用方法,这里只介绍多播组的结构体ip_mreq。

struct ip_mreq { struct in_addr imr_multiaddr; //多播组的IP地址 struct in_addr imr_interface; //加入的客服端主机IP地址 }

实现多播 1,发送者(Sender)

#define BUF_SIZE 30void error_handling(char *message);int main(int argc, const char * argv[]) {int send_sock;struct sockaddr_in mul_adr;int time_live = TTL;FILE *fp;char buf[BUF_SIZE];if (argc != 3) {printf(“Usage : %s <GroupIp> <Port> \n”, argv[0]);exit(1);}//基于UDP的多播send_sock = socket(PF_INET, SOCK_DGRAM, 0);memset(&mul_adr, 0, sizeof(mul_adr));mul_adr.sin_family = AF_INET;mul_adr.sin_addr.s_addr = inet_addr(argv[1]);mul_adr.sin_port = htons(atoi(argv[2]));//设置生存时间(除了这里其它基本和UDP编写一样)setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live));if((fp = fopen(“/Users/app05/Desktop/test.txt”, “r”)) == NULL)error_handling(“fopen() error”);while (!feof(fp)) //如果文件结束,则返回非0值,否则返回0{fgets(buf, BUF_SIZE, fp);sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_adr, sizeof(mul_adr));sleep(1); //只是为了加个传输数据时间间隔,没有特殊意义}fclose(fp);close(send_sock);return 0;}void error_handling(char *message){fputs(message, stderr);fputc(‘\n’, stderr);exit(1);}

2,接受者(Receiver)

error_handling(char *message);int main(int argc, const char * argv[]) {int recv_sock;int str_len;char buf[BUF_SIZE];struct sockaddr_in adr;struct ip_mreq join_adr; //多播组结构体if(argc != 3){printf(“Usage : %s <GroupIp> <Port> \n”, argv[0]);exit(1);}recv_sock = socket(PF_INET, SOCK_DGRAM, 0);memset(&adr, 0, sizeof(adr));adr.sin_family = AF_INET;adr.sin_addr.s_addr = htonl(INADDR_ANY);adr.sin_port = htons(atoi(argv[2]));if(bind(recv_sock, (struct sockaddr *)&adr, sizeof(adr)) == -1)error_handling(“bind() error”);//加入多播组join_adr.imr_multiaddr.s_addr = inet_addr(argv[1]);join_adr.imr_interface.s_addr = htonl(INADDR_ANY);setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr));while (1) {str_len = recvfrom(recv_sock, buf, BUF_SIZE – 1, 0, NULL, 0);//只需要多播组IP地址,不关心自己主机地址if(str_len < 0)break;buf[str_len] = 0;fputs(buf, stdout);}close(recv_sock);return 0;}void error_handling(char *message){fputs(message, stderr);fputc(‘\n’, stderr);exit(1);}

广播

广播在功能上和多播是一样的,都是同时可以向大量客户传递数据。但他们在网络范围上有区别,多播可以跨越不同的网络,只要加入了多播组就能接收数据。但广播只能向同一网络中的主机传输数据。 广播分为:直接广播与本地广播,直接广播sender的IP地址只需指定网络地址,主机地址全部填255。这样处在这个网络地址里的所有主机就可以接收数据了。而本地广播sender的IP地址写255.255.255.255,这样本地网络所有主机就可以接收数据了。

//将SO_BROADCAST可选项设置为1就表示开启了套接字广播功能,默认是关闭的。 int bcast = 1; setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void *) &bcast, sizeof(bcast));

当你困难失望的时候,最重要的是事瞧得起你自己;

TCP/IP网络编程 学习笔记

相关文章:

你感兴趣的文章:

标签云: