南海網(wǎng)站智能推廣線(xiàn)上推廣的渠道和方法
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 網(wǎng)絡(luò)通信:單播、廣播、組播
本文目錄:
一、網(wǎng)絡(luò)通信的分類(lèi)、他們的定義和特點(diǎn)。
二、單播、廣播、組播的傳輸信息的網(wǎng)絡(luò)拓?fù)淠P汀?/span>
三、單播、廣播、組播的編程實(shí)例。
一、網(wǎng)絡(luò)通信的分類(lèi)、他們的定義和特點(diǎn)。
二、單播、廣播、組播的傳輸信息的網(wǎng)絡(luò)拓?fù)淠P汀?/strong>
(一)單播
如圖8-1 所示,網(wǎng)絡(luò)中存在信息發(fā)送者Source,UserA 和UserC 提出信息需求,網(wǎng)絡(luò)采用單播方式傳輸信息。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
單播傳輸特點(diǎn)歸納如下:
* Source 向每個(gè)Receiver 地址發(fā)送一份獨(dú)立的拷貝信息:packets for UserA;packets for UserC。
* 網(wǎng)絡(luò)為每個(gè)Receiver 分別建立一條獨(dú)立的數(shù)據(jù)傳送通路:Source→ RouterB → RouterE → RouterD → UserA;Source → RouterB → RouterE → RouterF → UserC。
單播方式下,網(wǎng)絡(luò)中傳輸?shù)男畔⒘亢托枨笤撔畔⒌挠脩?hù)量成正比,當(dāng)需求該信息的用戶(hù)量較大時(shí),網(wǎng)絡(luò)中將出現(xiàn)多份相同信息流。此時(shí),帶寬成為保證網(wǎng)絡(luò)傳輸質(zhì)量的重要瓶頸。
單播方式較適合用戶(hù)稀少的網(wǎng)絡(luò),不利于信息規(guī)?;l(fā)送。
(二)廣播
如圖8-2 所示,網(wǎng)絡(luò)中存在信息發(fā)送者Source,UserA 和UserC 提出信息需求,網(wǎng)絡(luò)采用廣播方式傳輸信息。
? ? ? ? ? ? ? ? ? ? ? ? ? ??
廣播傳輸特點(diǎn)歸納如下:
* Source 向本網(wǎng)絡(luò)廣播地址發(fā)送且僅發(fā)送一份報(bào)文:packets for all the network。
* 網(wǎng)絡(luò)將報(bào)文拷貝傳送到所有網(wǎng)段,不管是否需要,保證信息到達(dá)網(wǎng)絡(luò)中所有的路由器和用戶(hù):UserB 也同樣接收到一份拷貝。
廣播方式下,網(wǎng)絡(luò)中所有用戶(hù)都能接收到該信息,當(dāng)網(wǎng)絡(luò)中需求該信息的用戶(hù)量很小時(shí),網(wǎng)絡(luò)資源利用率將非常低,帶寬浪費(fèi)嚴(yán)重。不需要這些信息的用戶(hù)也會(huì)受到影響。
廣播方式較適合用戶(hù)稠密的網(wǎng)絡(luò),信息安全性和有償服務(wù)得不到保障。?
(三)多播
如圖8-3 所示,網(wǎng)絡(luò)中存在信息發(fā)送者Source、UserA 和UserC 提出信息需求,網(wǎng)絡(luò)采用組播方式傳輸信息。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
組播傳輸特點(diǎn)歸納如下:
* Multicast group 稱(chēng)為組播組,使用一個(gè)IP 組播地址標(biāo)識(shí)。UserA 和UserC 兩個(gè)信息接收者,加入該組播組,從而可以接收發(fā)往該組播組的數(shù)據(jù)。
* Source 稱(chēng)為組播源,向該組播組地址發(fā)送且僅發(fā)送一份報(bào)文:packets for the multicast group。網(wǎng)絡(luò)傳輸過(guò)程中,相同的組播數(shù)據(jù)流在每一條鏈路上最多僅有一份。相比單播來(lái)說(shuō),使用組播方式傳遞信息,用戶(hù)的增加不會(huì)顯著增加網(wǎng)絡(luò)的負(fù)載。
* 根據(jù)組播組成員的分布情況,組播路由協(xié)議為多目的端的數(shù)據(jù)包轉(zhuǎn)送建立樹(shù)型路由。報(bào)文在盡可能遠(yuǎn)的分叉路口(如RouterE)才開(kāi)始復(fù)制和分發(fā),最終傳送到組播組成員。相比廣播來(lái)說(shuō),組播數(shù)據(jù)僅被傳輸?shù)接薪邮照叩牡胤?#xff0c;不會(huì)造成網(wǎng)絡(luò)資源的浪費(fèi)。
* 網(wǎng)絡(luò)中支持組播功能的路由器稱(chēng)為“組播路由器”,不僅提供組播路由功能,還能夠在與網(wǎng)絡(luò)用戶(hù)連接的末梢網(wǎng)段上提供組成員管理功能(如RouterD 和RouterF)。同時(shí),自己本身也可能是組播組成員。
* 組播組中的成員是動(dòng)態(tài)的,網(wǎng)絡(luò)中的用戶(hù)主機(jī)可以在任何時(shí)刻加入和離開(kāi)組播組。組成員可能廣泛分布在網(wǎng)絡(luò)中的任何地方。組播源通常不會(huì)同時(shí)是其發(fā)送數(shù)據(jù)的接收者,即不屬于其對(duì)應(yīng)的目的組播組。
* 一個(gè)源可以同時(shí)向多個(gè)組播組發(fā)送數(shù)據(jù);多個(gè)源可以同時(shí)向一個(gè)組播組發(fā)送報(bào)文。
* 為了幫助理解,可以類(lèi)比收看某電視頻道的節(jié)目。
* 組播組是發(fā)送者和接收者之間的一個(gè)約定,如同電視頻道。
* 電視臺(tái)是組播源,它向某頻道內(nèi)發(fā)送數(shù)據(jù)。
* 電視機(jī)是接收者主機(jī),觀眾打開(kāi)電視機(jī)選擇收看某頻道的節(jié)目,表示主機(jī)加入某組播組;然后電視機(jī)播放該頻道電視節(jié)目,表示主機(jī)接收到發(fā)送給這個(gè)組的數(shù)據(jù)。
* 觀眾可以隨時(shí)控制電視機(jī)的開(kāi)關(guān)和頻道間的切換,表示主機(jī)動(dòng)態(tài)的加入或退出某組播組。
三、單播、廣播、組播的編程實(shí)例。
(1)單播實(shí)例:(一個(gè)echo服務(wù)器,可以同時(shí)和多個(gè)用戶(hù)通信)
head.h
<span style="font-size:12px;">#ifndef _HEAD_H_
#define _HEAD_H_#include<stdio.h>
#include<string.h>
#include<strings.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<error.h>
#include<errno.h>
#include<unistd.h> //fork
#include<sys/wait.h>#define SER_PORT 50004
#define SER_IP "192.168.192.128"
#define CLIENT_PORT 50000
#define CLIENT_IP "192.168.192.128"#define BUFF_SIZE 100
#define SIZE 20typedef struct _USER
{char name[SIZE];char passwd[SIZE];
}usr;
#define sys_err(_msg) error(EXIT_FAILURE,errno,_msg)
/*errno是個(gè)全局變量,調(diào)用之后,可以在發(fā)生錯(cuò)誤的情況下,也能輸出——msg信息
*作為調(diào)試用
* */
#endif
</span>
server.c
<span style="font-size:12px;">#include "head.h"
int socket_init()
{int sockfd;struct sockaddr_in sockaddr;if((( sockfd=socket(AF_INET,SOCK_STREAM,0))==-1))sys_err("socket");bzero(&sockaddr,sizeof(sockaddr));sockaddr.sin_family=AF_INET;sockaddr.sin_port=htons(SER_PORT);sockaddr.sin_addr.s_addr=inet_addr("127.0.0.1");printf("%d=====\n",sockfd);if((bind(sockfd,(struct sockaddr*)&sockaddr,sizeof(sockaddr)))==-1)sys_err("bind");listen(sockfd,5); //要懂得監(jiān)聽(tīng)的作用,其實(shí)就是建立一個(gè)緩沖隊(duì)列,讓創(chuàng)建的隊(duì)列最多可以允許五個(gè)套接字進(jìn)入return sockfd;
}int do_echo(int connectfd)
{char sbuf[BUFF_SIZE];char rbuf[BUFF_SIZE];int n;printf("int the server ==========\n");while(1){printf("===============in the do_echo\n");bzero(rbuf,BUFF_SIZE);if((n=recv(connectfd,rbuf,BUFF_SIZE,0))==-1)sys_err("recv");if(n==0) //如果接受為0,代表客戶(hù)端已經(jīng)斷線(xiàn),返回-1return -1;printf("server:rbuf==%s\n",rbuf);sprintf(sbuf,"%s %s",rbuf,"---------echo");send(connectfd,sbuf,strlen(sbuf),0);}return ;
}
int main(int argc,const char * argv[])
{//步驟:/**1 創(chuàng)建套接字socket();*2 與IP地址綁定bind();*3監(jiān)聽(tīng) listen();*4如果有鏈接,接受鏈接,進(jìn)行三次握手accept();*5與客戶(hù)端進(jìn)行數(shù)據(jù)的傳輸read(),send();*6關(guān)閉套接字close(sockfd);* *注意:要掌握熟練掌握各個(gè)接口的調(diào)用* 為了實(shí)現(xiàn)多客戶(hù)端和服務(wù)器的交互,該怎么做* */int sockfd;//具有基本屬性的套接字描述符int connectfd;//進(jìn)行三次握手之后的套接字描述符sockfd=socket_init();//listen(sockfd,5); //要懂得監(jiān)聽(tīng)的作用,其實(shí)就是建立一個(gè)緩沖隊(duì)列,讓創(chuàng)建的將要//連接的套接字描述符進(jìn)隊(duì)和出隊(duì)
/**** The accept() system call is used with connection-based socket types* (SOCK_STREAM, SOCK_SEQPACKET). It extracts the first connection request on the* queue of pending connections for the listening socket, sockfd, creates a new*** */pid_t pid;signal(SIGCHLD,SIG_IGN);while(1){connectfd=accept(sockfd,NULL,NULL); //一個(gè)服務(wù)器可以和多個(gè)客戶(hù)端進(jìn)程多次握手連接。 切記,connect()函數(shù)在UDP協(xié)議中也可以用,不是TCP的專(zhuān)用if(connectfd == -1)sys_err("accept");if(-1==(pid=fork())){perror("fork");}else if(pid==0){printf("do_echo===%d\n", do_echo(connectfd));close(connectfd); //將子進(jìn)程從父進(jìn)程復(fù)制到的套接字資源,關(guān)閉了close(sockfd);}}
close(connectfd);//父進(jìn)程關(guān)閉自己的套接字close(sockfd);return 0;}</span><span style="font-size:14px;">
</span>
(2)廣播實(shí)例:
sender.c ?:
<span style="font-size:14px;">#include"head.h"
int main(int argc,const char * argv[])
{int sockfd;struct sockaddr_in sockaddr;char rbuf[BUFF_SIZE];if(-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0))) //由于TCP只支持一對(duì)一通信,UDP可以一對(duì)一,一對(duì)多,多對(duì)一,多對(duì)多。由于這個(gè)廣播。是多對(duì)多。所以只能是SOCK_DGRAM
perror("socket");bzero(&sockaddr,sizeof(sockaddr));sockaddr.sin_family=AF_INET;sockaddr.sin_port=htons(BRAOD_PORT); //#define BRAOD_PORT 50001sockaddr.sin_addr.s_addr=inet_addr(BRAOD_IP);//#define BRAOD_IP "192.168.1.255"if(-1==bind(sockfd,(struct sockaddr *)&sockaddr,sizeof(sockaddr)))perror("bind");while(1){bzero(&rbuf,sizeof(rbuf));recvfrom(sockfd,rbuf,BUFF_SIZE,0,(struct sockaddr*)&sockaddr,sizeof(sockaddr));printf("--------%s-------\n",rbuf);}close(sockfd);return 0;
}</span>
(3)組播實(shí)例:
sender.c :
<span style="font-size:14px;">#include"head.h"
int main(int argc ,const char * argv[])
{/**創(chuàng)建組播發(fā)送方的步驟:*創(chuàng)建套接字*設(shè)置組播地址(可選)*發(fā)送數(shù)據(jù)*關(guān)閉套接字* */int sockfd;struct sockaddr_in multiaddr;char sbuf[BUFF_SIZE]="hello,xiaowang....\n";int n;if(-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))perror("socket");bzero(&multiaddr,sizeof(multiaddr));multiaddr.sin_family=AF_INET;multiaddr.sin_port=htons(MULTI_PORT); //#define MULTI_PORT 50002 只要是用戶(hù)自定義端口即可multiaddr.sin_addr.s_addr=inet_addr(MULTI_IP);</span>
<span style="font-size:14px;"> //#define MULTI_IP "224.4.4.4" D類(lèi)地址是組播地址224.0.0.1---239.255.255.254while(1){sleep(1);if(-1==(n=sendto(sockfd,sbuf,strlen(sbuf),0,(struct sockaddr*)&multiaddr,sizeof(multiaddr))))perror("sendto");printf("in the sending..........\n");} return 0;
}</span>
recevier.c :
<span style="font-size:14px;">#include"head.h"
int main(int argc,const char * argv[])
{int sockfd;int n;char rbuf[BUFF_SIZE];struct sockaddr_in groupaddr;//創(chuàng)建套接字if(-1==(sockfd=socket(AF_INET,SOCK_DGRAM,0)))perror("socket");//加入組播struct ip_mreqn multiaddr; //這些在Man 2 setsockopt 時(shí)在signal的有關(guān)描述中可以查到的multiaddr.imr_multiaddr.s_addr=inet_addr(MULTI_IP);multiaddr.imr_address.s_addr=inet_addr(LOCAL_IP);multiaddr.imr_ifindex=0;//設(shè)置套接字允許發(fā)送組播信息的屬性if(-1==setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&multiaddr,sizeof(multiaddr)))perror("setsockopt");//綁定組播地址bzero(&groupaddr,sizeof(groupaddr));groupaddr.sin_family=AF_INET;groupaddr.sin_port=htons(MULTI_PORT);groupaddr.sin_addr.s_addr=inet_addr(MULTI_IP);bind(sockfd,(struct sockaddr*)&groupaddr,sizeof(groupaddr));int t;while(1){// bzero(&rbuf,sizeof(rbuf));t=sizeof(groupaddr);if(-1==(n=recvfrom(sockfd,rbuf,BUFF_SIZE,0,(struct sockaddr*)&groupaddr,&t)))perror("recvfrom");sleep(1); printf("%s-----------\n",rbuf);}return 0;
}
</span>
?
參考文獻(xiàn):http://www.xici.net/d79537500.htm
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 未經(jīng)允許,禁止轉(zhuǎn)載