单播 1.发送者 打开socket
connfd = socket(AF_INET,SOCK_DGRAM,0)
设置发送地址和端口
struct sockaddr_in si;
si.sin_family = AF_INET; // 套接字地址簇,一般使用AF_INET
si.sin_port = htons(端口); // 16位端口,网络序
si.sin_addr.s_addr = inet_addr(IP地址); // IP地址,网络序
发送数据
sendto(connfd,buf,buf_size,0,(struct sockaddr *)&si,sizeof(si));
关闭socket
close(connfd);
2.接受者 打开socket
int connfd = socket(AF_INET, SOCK_DGRAM, 0);
设置接收地址和端口
struct sockaddr_in si;
si.sin_family = AF_INET; // 套接字地址簇,一般使用AF_INET
si.sin_port = htons(端口); // 16位端口,网络序
si.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY表示接收来自任意IP、任意网卡的发给指定端口的数据
端口绑定
int ret = bind(connfd, (struct sockaddr *)&si, sizeof(si));
接收数据
recv(connfd,buf,buf_size,0);
关闭socket
close(connfd);
** unicast_recv.cpp**
#include<iostream>
#include<thread>
#include<arpa/inet.h>
#include<unistd.h>
#include<strings.h>
using namesapce std;
./unicast_recv IP port
int main(int argc,char* argv[]){
if(3!=argc){
cout<<"usage:"<<argv[0]<<"ip port"<<endl;
return 1;
}
//1.创建套接字
int connfd=socket(AF_INET,SOCK_DGRAM,0);
if(connfd==-1){
cout<<"create socket error";
return 1;
}
//2.绑定端口和地址
struct sockaddr_in local_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr=inet_addr(argv[1]);
local_addr.sin_port=htons(atoi(argv[2]));
if(-1==bind(connfd,(struct sockaddr*)&local_addr,sizeof(local_addr) )){
cout<<"bind error"<<endl;
return 1;
}
struct sockaddr_in remote_addr;
bzero(&remote_addr,sizeof(remote_addr));
socklen_t len;
thread([&]{
for(;;){
//接收数据
char buffer[1024];
recvfrom(connfd,buffer,1024,0,(struct sockaddr*)&remote_addr,&len);
cout<<buffer<<endl;
}
}).detach();
for(;;){
//发送数据
string message;
getline(cin,message);
sendto(connfd,message.c_str(),message.size()+1,0,(struct sockaddr* )&remote_addr,len);
}
close(connfd);
}
** unicast_send IP port**
#include<iostream>
#include<thread>
#include<arpa/inet.h>
#include<unistd.h>
using namespace std;
int main(){
if(argc!=3){
cout<<"usage:"<<argv[0]<<"IP port"<<endl;
return 1;
}
//1.创建套接字
int connfd=socket(AF_INET,SOCK_DGRAM,0);
if(connfd==-1){
cout<<"create socket error"<<endl;
return 1;
}
//2.绑定端口和地址
struct sock_addr_in local_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr=inet_addr(argv[1]);
local_addr.sin_port=htons(atoi(argv[2]));
thread([=]{
for(;;){
//发送数据
string message;
getline(cin,message);
sendto(connfd,message.c_str(),message.size()+1,0,(struct sockaddr*)&local_addr,sizeof(local_addr));
}
}).detach();
for(;;){
//接收数据
char buffer[1024];
socklen_t len=sizeof(local_addr);
recvfrom(connfd,buffer,1024,0,(struct sockaddr*)&local_addr,&len);
cout<<buffer<<endl;
}
//关闭套接字
close(connfd);
}
组播 1.发送者(与单播发送者一致) 2.接受者 打开套接字
int socket(int domain, int type, int protocol); 返回套接字
构建服务器地址结构
struct sockaddr_in serveraddr;
bzero(&serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); //IP
serveraddr.sin_port = htons(SERVER_PORT);//端口
绑定地址
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
构建组播属性结构
struct ip_mreqn group;
inet_pton(AF_INET,GROUP,&group.imr_multiaddr);//设置组播地址
inet_pton(AF_INET,"0.0.0.0",&group.imr_address);//设置本地地址
group.imr_ifindex=if_nametoindex("ent0");//设置网卡接口
设置组播权限和属性
setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_IF,&group,sizeof(group));//设置组播权限及选项
设置客户端组播地址
struct sockaddr_in cliaddr;
bzero(&cliaddr,sizeof(cliaddr));
cliaddr.sin_family=AF_INET;
inet_pton(AF_INET,GROUP,&cliaddr.sin_addr.s_addr);
cliaddr.sin_port=htons(CLIENT_PORT);
发送数据
sendto(sockfd,buf,strlen(buf),0,(structsockaddr*)&cliaddr, sizeof(cliaddr));//往组播地址发送信息,返回数据大小
关闭套接字
close(fd);
#include<iostream>
#include<thread>
#include<arpa/inet.h>
#include<unistd.h>
#include<strings.h>
using namespace std;
int main(int argc,char* argv[]){
if(argc!=4){
cout<<"usage"<<argv[0]<<"ip port multiIp"<<endl;
return 1;
}
//创建套接字
int connfd=socket(AF_INET,SOCK_DGRAM,0);
if(connfd==-1){
cout<<"create socket error"<<endl;
return 1;
}
//绑定端口和地址
struct sockaddr_in local_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr=inet_addr(argv[1]);
local_addr.sin_port=htons(atoi(argv[2]));
if(-1==bind(connfd,(struct sockaddr*)&local_addr,sizeof(local_addr))){
cout<<"bind error"<<endl;
}
//设置组播地址
struct ip_mreq group;
group.imr_interface.s_addr=inet_addr(argv[1]);
group.imr_multiaddr.s_addr=inet_addr(argv[3]);
if(-1==setsockopt(connfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&group,sizeof(group))){
cout<<"multicast setting error "<<endl;
return 1;
}
struct sockaddr_in remote_addr;
bzero(&remote_addr,sizeof(remote_addr));
socklen_t len;
thread([&]{
for(;;){
//接收数据
char buffer[1024];
recvfrom(connfd,buffer,1024,0,(struct sockaddr*)&remote_addr,&len);
cout<<buffer<<endl;
}
}).detach();
for(;;){
//发送数据
string message;
getline(cin,message);
sendto(connfd,message.c_str(),message.size()+1,0,(struct sockaddr*)&remote_addr,len);
}
close(connfd);
}
广播 1.发送者 打开socket 打开广播 设置发送地址和端口 发送数据 关闭socket
#include<iostream>
#include<thread>
#include<arpa/inet.h>
#include<unistd.h>
using namespace std;
//./unicast_send IP port
int main(int argc,char* argv[]){
if(argc!=3){
cout<<"usage:"<<argv[0]<<"IP Port"<<endl;
return 1;
}
//创建套接字
int connfd=socket(AF_INET,SOCK_DGRAM,0);
if(connfd==-1){
cout<<"create socket error"<<endl;
return 1;
}
//设置广播
int flag=1;
if(-1==setsockopt(connfd,SOL_SOCKET,SO_BROADCAST,&flag,sizeof(flag))){
cout<<"broadcast setting error"<<endl;
return 1;
}
//绑定端口和地址
struct sockaddr_in local_addr;
local_addr.sin_family=AF_INET;
local_addr.sin_addr.s_addr=inet_addr(argv[1]);
local_addr.sin_port=htons(atoi(argv[2]));
thread([=]{
for(;;){
//发送数据
string message;
getline(cin,message);
sendto(connfd,message.c_str(),message.size()+1,0,(struct sockaddr*)&local_addr,sizeof(local_addr));
}
}).detach();
for(;;){
//接收数据
char buffer[1024];
socklen_t len=sizeof(local_addr);
recvfrom(connfd,buffer,1024,0,(struct sockaddr*)&local_addr,&len);
cout<<buffer<<endl;
}
//关闭套接字
close(connfd);
}
2.接受者(与单播发送者一致)