一、思维导图
二、广播
广播发送端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
//2、设置允许广播
int broadcast = 1;
if(setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&broadcast,sizeof(broadcast)) ==-1)
{
perror("setsockopt errror");
return -1;
}
//3、绑定(可选)
//4、填充接收端地址信息结构体
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(8888);
rin.sin_addr.s_addr = inet_addr("192.168.117.255");
//5、发送消息
char sbuf[128] = "";
while(1)
{
printf("请输入>>>");
fgets(sbuf,sizeof(sbuf),stdin);
sbuf[strlen(sbuf)-1] = 0;
//将数据发送出去
sendto(sfd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&rin,sizeof(rin));
printf("发送成功\n");
}
//6、关闭套接字
close(sfd);
return 0;
}
广播接收端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建用于通信的套接字
int rfd = socket(AF_INET,SOCK_DGRAM,0);
if(rfd == -1)
{
perror("socket error");
return -1;
}
printf("rfd = %d\n",rfd);
//2、绑定IP地址和端口号
//2.1填充地址信息结构体
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(8888);
rin.sin_addr.s_addr = inet_addr("192.168.117.255");
//2.2绑定
if(bind(rfd,(struct sockaddr*)&rin,sizeof(rin)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、接收消息
char rbuf[128] = "";
while(1)
{
//清空容器
bzero(rbuf,sizeof(rbuf));
//从套接字中读取数据
recv(rfd,rbuf,sizeof(rbuf),0);
printf("收到消息为:%s\n",rbuf);
}
//4、关闭套接字
close(rfd);
return 0;
}
广播效果图
三、组播
组播发送端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
//2、bind连接(非必须)
//3.1、填充接收端地址信息结构体
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(8888);
rin.sin_addr.s_addr = inet_addr("224.1.2.3"); //组播IP
//4、发送信息
char sbuf[128] ="";
while(1)
{
printf("请输入>>>");
fgets(sbuf,sizeof(sbuf),stdin);
sbuf[strlen(sbuf)-1] = 0;
//将数据发送出去
sendto(sfd,sbuf,sizeof(sbuf),0,(struct sockaddr*)&rin,sizeof(rin));
printf("发送成功\n");
}
//5、关闭套接字
close(sfd);
return 0;
}
组播接收端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建套接字
int rfd = socket(AF_INET,SOCK_DGRAM,0);
if(rfd == -1)
{
perror("socket error");
return -1;
}
//2、设置网络属性加入多播组
struct ip_mreqn im;
im.imr_multiaddr.s_addr = inet_addr("224.1.2.3");//组播IP
im.imr_address.s_addr =inet_addr("192.168.117.117");//主机IP
im.imr_ifindex = 2;
//设置网络属性
if(setsockopt(rfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&im,sizeof(im)) ==-1)
{
perror("socketopt error");
return -1;
}
printf("加入多播组成功\n");
//3、绑定IP和端口号
//3.1、填充地址信息结构体
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(8888);
rin.sin_addr.s_addr = inet_addr("224.1.2.3"); //组播IP
//3.2、绑定
if(bind(rfd,(struct sockaddr*)&rin,sizeof(rin)) == -1)
{
perror("bind error");
return -1;
}
//4、接收数据
char rbuf[128]= "";
while(1)
{
//清空容器
bzero(rbuf,sizeof(rbuf));
//从套接字中读取数据
recv(rfd,rbuf,sizeof(rbuf),0);
printf("收到消息为:%s\n",rbuf);
}
//5、关闭套接字
close(rfd);
return 0;
}
组播效果图
四、流式域套接字
流式域套接字服务器端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建用于连接的套接字文件描述符
int sfd = socket(AF_UNIX,SOCK_STREAM,0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success sfd = %d\n",sfd);
//判断要绑定的套接字是否存在
if(access("./unix",F_OK) == 0)
{
//将该文件删除
if(unlink("./unix") == -1)
{
perror("unlink error");
return -1;
}
}
//2、绑定套接字文件
//2.1填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,"./unix");
if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3.启动被动监听
if(listen(sfd,128) == -1)
{
perror("listen error");
return -1;
}
//4.、等待客户端连接请求
//4.1、定义地址信息结构体,用于接受客户地址信息结构体
struct sockaddr_un cun;
socklen_t socklen = sizeof(cun);
//4.2、接受客户端
int newfd = accept(sfd,(struct sockaddr*)&cun,&socklen);
if(newfd == -1)
{
perror("accept errro");
return -1;
}
//5、互相通信
char rbuf[128] = ""; //用于接受客户发来的数据
while(1)
{
//将容器清空
bzero(rbuf,sizeof(rbuf));
//从套接字中读取数据
int res = recv(newfd,rbuf,sizeof(rbuf)-1,0);
if(res == 0)
{
printf("客户端已经下线\n");
break;
}
printf("[%s]:%s\n",cun.sun_path,rbuf);
//加上收到回复客户端
strcat(rbuf," <Got it!>");
send(newfd,rbuf,strlen(rbuf),0);
printf("回复成功\n");
}
//6、关闭服务器
close(newfd);
close(sfd);
return 0;
}
流式域套接字客户端
#include<myhead.h>
int main(int argc, const char *argv[])
{
//1、创建用于连接客户端的套接字
int cfd = socket(AF_UNIX,SOCK_STREAM,0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success cfd = %d\n",cfd);
//判断要绑定的套接字是否存在
if(access("./linux",F_OK) == 0)
{
//将该文件删除
if(unlink("./linux") == -1)
{
perror("unlink error");
return -1;
}
}
//2、绑定套接字文件
//2.1、填充客户端地址信息结构体
struct sockaddr_un cun;
cun.sun_family = AF_UNIX;
strcpy(cun.sun_path,"./linux");
//2.2、绑定端口号和IP
if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3、连接服务器
//3.1填充要连接服务器的地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,"unix");
//3.2、连接服务器
if(connect(cfd,(struct sockaddr*)&sun,sizeof(sun)) == -1)
{
perror("connect error");
return -1;
}
printf("连接成功\n");
//4、收发数据
char wbuf[128] ="";
while(1)
{
printf("请输入>>>");
fgets(wbuf,sizeof(wbuf),stdin); //从终端获取字符串
wbuf[strlen(wbuf)-1] = '\0'; //将换行换成'\0'
//判断输入的字符串值
if(strcmp(wbuf,"quit") == 0)
{
break;
}
//将数据发送给服务器
send(cfd,wbuf,strlen(wbuf),0);
//将字符数组清空
bzero(wbuf,sizeof(wbuf));
recv(cfd,wbuf,sizeof(wbuf)-1,0);
printf("收到的服务器消息为:%s\n",wbuf);
}
//5、关闭套接字
close(cfd);
return 0;
}