广播代码
接收
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8888
#define IP "192.168.8.255"
#define ERR_MSG(msg) do{\
fprintf(stdout, "%d", __LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
//创建广播接收端
//创建套接字
int ufd = socket(AF_INET, SOCK_DGRAM, 0);
if(ufd < 0)
{
ERR_MSG("socket");
return -1;
}
puts("socket success");
//填充服务器的IP和端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT); //端口号
sin.sin_addr.s_addr = inet_addr(IP); //IP
//绑定IP地址和端口号
if(bind(ufd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
puts("bind success");
char buf[128] = "";
//如果想知道数据包从谁那发过来
//需要定义地址数据结构体和长度来接收
struct sockaddr_in cin;
socklen_t addrlen;
while(1)
{
//接收数据
//if(recvfrom(ufd, buf, sizeof(buf), 0, NULL, NULL) < 0)
if(recvfrom(ufd, buf, sizeof(buf), 0, (struct sockaddr *)&cin, &addrlen) < 0)
{
ERR_MSG("recvfrom");
return -1;
}
puts("recvfrom success");
//终端显示数据
printf("%s : %d buf:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
}
//关闭套接字
close(ufd);
return 0;
}
发送
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define ERR_MSG(msg) do{\
fprintf(stdout, "%d", __LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
//创建套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
puts("socket success");
//填充服务器IP和端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.s_addr = inet_addr("192.168.8.255");
//设置允许广播
int broad = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0)
{
ERR_MSG("setsockopt");
return -1;
}
/*
//当udp中使用connect时
//只能和指定的服务器或客户端通信
//同时sendto和recvfrom可以改成send和recv
//如果继续使用sendto和recvfrom,要把后面参数改成NULL,0和NULL, NULL
if(connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
ERR_MSG("connect");
return -1;
}
puts("connect success");
*/
char buf[128] = "";
while(1)
{
//客户端发送数据包给服务器
printf("请输入:");
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = 0;
if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
//if(send(sfd, buf, sizeof(buf), 0) < 0)
{
ERR_MSG("sendto");
return -1;
}
puts("sendto success");
}
//关闭套接字
close(sfd);
return 0;
}
tftp协议
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
int do_download(int sfd, struct sockaddr_in sin);
int do_upload(int sfd, struct sockaddr_in sin);
#define ERR_MSG(msg) do{\
fprintf(stdout, "%d", __LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
//客户端
//创建套接字文件
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
puts("socket success");
//填充服务器地址结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(69);
sin.sin_addr.s_addr = inet_addr("192.168.8.67");
//选择是上传还是下载,或者退出
char c = 0;
while(1)
{
printf("------------------------------\n");
printf("-----------1. 上传------------\n");
printf("-----------2. 下载------------\n");
printf("-----------3. 退出------------\n");
printf("------------------------------\n");
printf("请输入>>>");
c = getchar();
while(getchar()!=10);
switch(c)
{
case '1':
do_upload(sfd, sin);
break;
case '2':
do_download(sfd, sin);
break;
case '3':
goto END;
break;
default:
printf("输入错误,请重新输入!\n");
}
}
END:
//关闭套接字文件
close(sfd);
return 0;
}
int do_download(int sfd, struct sockaddr_in sin)
{
//读写请求
char buf[520] = "";
unsigned short *pa =(unsigned short *)buf;
*pa = htons(1);
printf("请输入需要下载的文件名:");
char name[20] = "";
scanf("%s", name);
char *pb = buf + 2;
strcpy(pb, name);
char *pd = pb + strlen(pb) + 1;
strcpy(pd, "octet");
int size = strlen(pb) + strlen(pd) + 4;
//发送读写请求
if(sendto(sfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
puts("sendto success");
ssize_t res = 0;
socklen_t addrlen = sizeof(sin);
unsigned short count = 1; //块编号
unsigned short data;
int fd;
while(1)
{
//客户端接收数据包
bzero(buf, sizeof(buf));
res = recvfrom(sfd, buf, 516, 0, (struct sockaddr*)&sin, &addrlen);
if(res < 0)
{
ERR_MSG("recvfrom");
return -1;
}
if(buf[1] == 3)
{
if(count == ntohs(*(unsigned short*)(buf+2)))
{
int fd = open("./1.c", O_WRONLY|O_CREAT|O_APPEND, 0777);
if(fd < 0)
{
ERR_MSG("open");
return -1;
}
if(write(fd, buf+4, 512) < 0)
{
ERR_MSG("write");
return -1;
}
//客户端发送ack包
buf[1] = 4;
if(sendto(sfd, buf, 4, 0, (struct sockaddr*)&sin, addrlen) < 0)
{
ERR_MSG("sendto");
return -1;
}
if(res < 516) //数据长度小于512,停止发送
{
break;
}
count++;
}
}
else if(buf[1] == 5) //错误信息
{
printf("ERROR:%s\n",buf+4);
return -2;
}
}
return 0;
}
int do_upload(int sfd, struct sockaddr_in sin)
{
socklen_t addrlen = sizeof(sin);
char buf[520] = "";
ssize_t res = 0;
unsigned short count = 0; //块编号
//读写请求
//操作码
unsigned short* pa = (unsigned short*)buf;
*pa = htons(2);
//文件名
printf("请输入需要上传的文件名:");
char name[20] = "";
scanf("%s", name);
char *pb = buf + 2;
strcpy(pb, name);
//模式
char *pc = pb+1+strlen(pb);
strcpy(pc,"octet");
int size = 4+strlen(pb)+strlen(pc);
//发送读写请求
if(sendto(sfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
puts("sendto success");
//打开文件
int fd = open(name, O_RDONLY);
if(fd < 0)
{
ERR_MSG("open");
return -1;
}
while(1)
{
//接收同意ack包
bzero(buf, sizeof(buf));
if(recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, &addrlen) < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("ack包接收成功\n");
//错误信息
if(buf[1] == 5)
{
printf("ERROR:%s\n",buf+4);
return -1;
}
if(count == ntohs(*(unsigned short*)(buf+2)))
{
buf[1] = 3;
count++;
*(unsigned short*)(buf+2) = htons(count);
//读取文件
res = read(fd, buf+4, 512);
if(res < 0)
{
ERR_MSG("read");
return -1;
}
//上传文件
if(sendto(sfd, buf, 516, 0, (struct sockaddr*)&sin, addrlen) < 0)
{
ERR_MSG("sendto");
return -1;
}
if(res <512)
{
printf("文件读取完毕\n");
break;
}
}
else
{
printf("文件发送错误\n");
}
if(buf[1] == 5)
{
printf("ERROR:%s\n", buf+4);
return -1;
}
}
}