广播服务器端
#include
int main(int argc, char const *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
//填充网络信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(6789);
cin.sin_addr.s_addr = inet_addr("192.168.124.255");
//绑定
bind(sfd, (struct sockaddr *)&cin, sizeof(cin));
char buf[128] = "";
//接收广播消息
while (1)
{
memset(buf, 0, sizeof(buf));
recvfrom(sfd, buf, sizeof(buf), 0, NULL, NULL);
printf("接收到的消息:%s\n",buf);
}
//关闭套接字
close(sfd);
return 0;
}
广播客户端
#include
int main(int argc, char const *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
//将套接字设置成允许广播
int broadcase = 1;
if (setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broadcase, sizeof(broadcase)) == -1)
{
perror("setsockopt error");
return -1;
}
//填充网络信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(6789);
cin.sin_addr.s_addr = inet_addr("192.168.124.255");
//绑定非必要
//bind(sfd, (struct sockaddr *)&cin, sizeof(cin));
char buf[128] = "";
//发送广播消息
while (1)
{
memset(buf, 0, sizeof(buf));
printf("请输入--->");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
//发送到广播地址中去
sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, sizeof(cin));
printf("发送成功\n");
}
close(sfd);
return 0;
}
组播服务器端
#include
int main(int argc, char const *argv[])
{
//创建套接字
int rfd = socket(AF_INET, SOCK_DGRAM, 0);
if (rfd == -1)
{
perror("socket error");
return -1;
}
//设置网络属性
struct ip_mreqn im;
im.imr_multiaddr.s_addr = inet_addr("224.1.2.3");
im.imr_address.s_addr = inet_addr("192.168.125.193");
im.imr_ifindex = 2;
if (setsockopt(rfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &im, sizeof(im)) == -1)
{
perror("setsockopt error");
return -1;
}
puts("加入多播组成功");
//填充地址信息结构体
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(9999);
rin.sin_addr.s_addr = inet_addr("224.1.2.3");
//绑定
if (bind(rfd, (struct sockaddr *)&rin, sizeof(rin)) == -1)
{
perror("绑定成功");
return -1;
}
puts("绑定成功");
//接收消息
char buf[128]="";
while(1)
{
memset(buf,0,sizeof(buf));
recvfrom(rfd,buf,sizeof(buf),0,0,0);
printf("收到消息为:%s\n",buf);
}
//关闭套接字
close(rfd);
return 0;
}
组播客户端
#include
int main(int argc, char const *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd == -1)
{
perror("socket error");
return -1;
}
//发送端不用设置网络属性
//填充地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(9999);
sin.sin_addr.s_addr = inet_addr("224.1.2.3");
//绑定非必要
/*
if (bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
perror("绑定成功");
return -1;
}
puts("绑定成功");
*/
//发送消息
char buf[128] = "";
while (1)
{
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = 0;
//发送给指定IP端口
sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin));
printf("收到消息为:%s\n", buf);
}
//关闭套接字
close(sfd);
return 0;
}
流式域套接字
服务器端
#include
int main(int argc, const char *argv[])
{
//1、创建套接字
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
//int sfd = socket(AF_UNIX, SOCK_RAW, IPPROTO_TCP);
if (sfd == -1)
{
perror("socket error");
return -1;
}
//由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
//所以,在绑定之前需要判断当前文件是否存在
if (access("./unix", F_OK) == 0)
{
//表示文件存在,删除该文件
if (unlink("./unix") == -1)
{
perror("unlink error");
return -1;
}
}
//2、填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX; //通信域
//sun.sun_path = ".unix"; //字符串赋值不能使用赋值运算符
strcpy(sun.sun_path, "./unix"); //绑定套接字文件
//3、绑定地址信息结构体
if (bind(sfd, (struct sockaddr *)&sun, sizeof(sun)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//4、监听
if (listen(sfd, 128) == -1)
{
perror("listen error");
return -1;
}
//5、阻塞接收客户端链接请求
//定义容器接收客户端地址信息结构体
struct sockaddr_un cun;
socklen_t socklen = sizeof(cun);
int newfd = accept(sfd, (struct sockaddr *)&cun, &socklen); //表示不接收客户端地址信息
if (newfd == -1)
{
perror("accept error");
return -1;
}
//6、收发数据
char buf[128] = "";
while (1)
{
//清空数组
bzero(buf, sizeof(buf));
int res = recv(newfd, buf, sizeof(buf), 0); //读取消息
if (res == 0)
{
printf("客户端已经下线\n");
break;
}
printf("[%s]: %s\n", cun.sun_path, buf);
}
//7、关闭套接字
close(newfd);
close(sfd);
return 0;
}
客户端
#include
int main(int argc, char const *argv[])
{
//创建套接字
int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (cfd == -1)
{
perror("socket error");
return -1;
}
//判断Linux文件是否存在
if (access("./linux", F_OK) == 0)
{
if (unlink("./linux") == -1)
{
perror("unlink error");
return -1;
}
}
//填充信息结构体
struct sockaddr_un cun;
cun.sun_family = AF_UNIX;
strcpy(cun.sun_path, "./linux");
//绑定信息结构体
if (bind(cfd, (struct sockaddr *)&cun, sizeof(cun)) == -1)
{
perror("bind error");
return -1;
}
puts("bind success");
//连接服务器
//填充服务器地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, "./unix");
//连接服务器
connect(cfd, (struct sockaddr *)&sun, sizeof(sun));
//收发数据
char buf[128] = "";
while (1)
{
//清空数组
memset(buf, 0, sizeof(buf));
//获取消息内容
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = 0;
//发送消息
send(cfd, buf, sizeof(buf), 0);
printf("发送成功\n");
if (strcmp(buf, "quit") == 0)
{
break;
}
}
//关闭套接字
close(cfd);
return 0;
}
报式域套接字
服务器端
#include
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
printf("sfd = %d\n", sfd);
//由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
//所以,在绑定之前需要判断当前文件是否存在
if(access("./linux", F_OK) == 0)
{
//表示文件存在,删除该文件
if(unlink("./linux")==-1)
{
perror("unlink error");
return -1;
}
}
// 填充地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, "./linux");
// 绑定工作
if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun)) == -1)
{
perror("bind error");
return -1;
}
//数据收发
char buf[128] = "";
//定义变量存放客户端地址信息结构体
struct sockaddr_un cun;
socklen_t socklen = sizeof(cun);
while(1)
{
//清空数组
bzero(buf, sizeof(buf));
//从套接字文件中读取消息
recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, &socklen);
printf("[%s]:%s\n", cun.sun_path, buf);
//将字符串连接后回发
strcat(buf, "*.*");
//if(write(sfd, buf, sizeof(buf)) == -1)
if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, sizeof(cun)) == -1)
{
perror("sendto error");
return -1;
}
printf("发送成功\n");
}
//4、关闭套接字
close(sfd);
return 0;
}
客户端
#include
int main(int argc, const char *argv[])
{
//1、创建用于通信的套接字文件描述符
int cfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (cfd == -1)
{
perror("socket error");
return -1;
}
//由于域套接字的绑定函数,只能绑定一个不存在的套接字文件
//所以,在绑定之前需要判断当前文件是否存在
if (access("./unix", F_OK) == 0)
{
//表示文件存在,删除该文件
if (unlink("./unix") == -1)
{
perror("unlink error");
return -1;
}
}
//2、绑定
//2.1 填充地址信息结构体
struct sockaddr_un cun;
cun.sun_family = AF_UNIX;
strcpy(cun.sun_path, "./unix");
//2.2 绑定工作
if (bind(cfd, (struct sockaddr *)&cun, sizeof(cun)) == -1)
{
perror("bind error");
return -1;
}
//3、填充服务器的地址信息结构体
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path, "./linux");
//4、数据收发
char buf[128] = "";
while (1)
{
printf("请输入>>>");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
//发送给服务器
sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sun, sizeof(sun));
if (strcmp(buf, "quit") == 0)
{
break;
}
//接收服务器发送来的消息
recvfrom(cfd, buf, sizeof(buf), 0, NULL, NULL);
printf("收到消息:%s\n", buf);
}
//5、关闭套接字
close(cfd);
return 0;
}
使用TFTP协议完成客户端的文件上传下载功能
#include
int fileonload(int sockfd)
{
int sfd = sockfd;
printf("上传的文件:");
char file[64];
scanf("%s", file);
//打开文件用于读取上传文件的数据
int send_fd = -1;
if ((send_fd = open(file, O_RDONLY)) == -1)
{
perror("open error:");
return -1;
}
//填充信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(69);
sin.sin_addr.s_addr = inet_addr("192.168.125.60");
socklen_t socklen = sizeof(sin);
//封装请求下载数据包
//第一块
}
int main(int argc, char const *argv[])
{
// 创建套接字UDP通信
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd)
{
perror("socket error");
return -1;
}
// 填充服务器网络信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
//端口号填69
sin.sin_port = htons(69);
//填写windows ip地址
sin.sin_addr.s_addr = inet_addr("192.168.125.60");
//结构体长度
socklen_t socklen = sizeof(sin);
//数据包数据的长度以512字节传输
char buffer[516] = {0};
//返回的ACK
char ack[4];
//操作码
short code = 0;
//块编号 or 错误码
short BlockoErr = 0;
//数据的长度以512Byte传输
char text[512] = {0}; //文件内容 或 错误信息
//校验收到的块编号
int N = 0;
//返回的文件描述符
int fd;
int ret = 0;
//文件名
char filename[64] = {0};
while (1)
{
int chose = 0;
puts("1.下载");
puts("2.上传");
puts("3.退出");
scanf("%d", &chose);
switch (chose)
{
case 1:
memset(filename, 0, sizeof(filename));
//输入文件名
printf("下载文件名: ");
scanf("%s", filename);
//使用 sprintf 组包
//返回成功格式化字符的个数 01下载操作 10上传操作
ret = sprintf(buffer, "%c%c%s%c%s%c", 0, 1, filename, 0, "octet", 0);
//首次发送请求
if (-1 == sendto(sockfd, buffer, ret, 0, (struct sockaddr *)&sin, socklen))
{
perror("sendto error");
return -1;
}
//循环接收服务器发来的数据包
while (1)
{
//因为有临时端口需要保存服务器的网络信息结构体
ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&sin, &socklen);
if (-1 == ret)
{
perror("recvfrom error");
return -1;
}
//解析操作码
code = ntohs(*(short *)buffer);
//解析块编号or错误码
BlockoErr = ntohs(*(short *)(buffer + 2));
//解析文件内容or错误信息,并将内容放入数据段
strncpy(text, buffer + 4, sizeof(text));
//解析数据包中的内容
if (3 == code && BlockoErr == N + 1)
{
//校验块编号+1
N++;
//要接收的数据包
//如果是第一次接到数据包 要创建文件
if (BlockoErr == 1)
{
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0664);
if (-1 == fd)
{
perror("open error");
}
}
//将文件内容写入文件 留出4字节
if (-1 == write(fd, text, ret - 4))
{
perror("write error");
}
// 组装ACK
*(short *)ack = htons(4);
*(short *)(ack + 2) = htons(BlockoErr);
//回复ACK包
if (-1 == sendto(sockfd, ack, 4, 0, (struct sockaddr *)&sin, socklen))
{
perror("recvfrom error");
}
//文件接收完毕
if (ret < 512)
break;
}
}
printf("文件[%s]下载完成\n", filename);
close(sockfd);
break;
case 2:
memset(filename, 0, sizeof(filename));
//输入文件名
printf("上传文件名: ");
scanf("%s", filename);
int upfd = -1;
if ((upfd = open(filename, O_RDONLY)) == -1)
{
perror("open error:");
return -1;
}
short *p1 = (short *)buffer;
*p1 = htons(2);
//第二模块
char *p2 = buffer + 2;
strcpy(p2, filename);
//第三模块
char *p3 = p2 + strlen(p2) + 1;
strcpy(p3, "octet");
int len = 4 + strlen(p2) + strlen(p3);
sendto(sockfd, buffer, len, 0, (struct sockaddr *)&sin, sizeof(sin));
char *data_point = buffer + 4;
short *cmd_point = (short *)buffer;
*cmd_point = htons(3);
short *block_point = (short *)(buffer + 2);
*block_point = htons(1);
int i = 1;
while (1)
{
recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&sin, &socklen);
if (*cmd_point == htons(4))
{
int res = read(upfd, buffer + 4, 512);
if (res == 0)
{
break;
}
*cmd_point = htons(3);
sendto(sockfd, buffer, res + 4, 0, (struct sockaddr *)&sin, socklen);
}
}
printf("文件[%s]上传完成\n", filename);
close(sockfd);
break;
case 3:
exit(0);
default:
puts("error");
}
}
return 0;
}