一、思维导图
二、广播
广播发送端
#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");//组播IPim.imr_address.s_addr =inet_addr("192.168.117.117");//主机IPim.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、绑定端口号和IPif(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;
}
流式域套接字效果图