1. 将UDP的服务器客户端重新搭建
#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.151"
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 addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr *)&addr,sizeof(addr)))
{
ERR_MSG("bind");
return -1;
}
puts("bind success");
//接收数据
while(1)
{
char a[128]="\0";
struct sockaddr_in cli;
socklen_t clilen = sizeof(cli);
int ser = recvfrom(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,&clilen);
if(ser < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s:%d]%s\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port),a);
/*
printf("发送数据:");
fflush(stdout);
bzero(a,sizeof(a));
fgets(a,sizeof(a),stdin);
a[strlen(a)-1] = '\0';
*/
if(sendto(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,sizeof(cli)) < 0)
{
ERR_MSG("sendto");
return -1;
}
}
//发送数据
//关闭文件
close(sfd);
return 0;
}
#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.151"
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 addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr *)&addr,sizeof(addr)))
{
ERR_MSG("bind");
return -1;
}
puts("bind success");
//1
addr.sin_port = htons(2222);
addr.sin_addr.s_addr = inet_addr("192.168.10.149");
connect(sfd,(struct sockaddr *)&addr,sizeof(addr));
//2
addr.sin_family = AF_UNSPEC;
addr.sin_port = htons(2222);
addr.sin_addr.s_addr = inet_addr("192.168.10.149");
connect(sfd,(struct sockaddr *)&addr,sizeof(addr));
//接收数据
while(1)
{
char a[128]="\0";
struct sockaddr_in cli;
socklen_t clilen = sizeof(cli);
int ser = recvfrom(sfd,a,sizeof(a),0,(struct sockaddr *)&cli,&clilen);
if(ser < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s:%d]%s\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port),a);
}
//发送数据
//关闭文件
close(sfd);
return 0;
}
2. 编写tftp的下载代码
#include <myhead.h>
#define ERR_MSG(msg) fprintf(stderr,"%d\n",__LINE__);perror(msg);
#define IP "192.168.10.149"
typedef struct{
uint16_t opcode;
uint16_t block;
uint8_t data[512];
}datapag;
typedef struct{
uint16_t opcode;
uint16_t block;
}ack;
int download(int cfd,const struct sockaddr_in *addr,int addrlen)
{ //发送数据
char buf[128]="";
char *ptr = buf;
*(uint16_t *)ptr = htons(1);
ptr += 2;
char fname[20] = "";
printf("输入文件名:");
scanf("%s",fname);
strcpy(ptr,fname);
ptr += strlen(fname)+1;
strcpy(ptr,"octet");
if(sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)addr,addrlen) < 0)//发送请求
{
ERR_MSG("sendto");
return -1;
}
ack a={htons(4),htons(0)};//ack
int f = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0664);//打开文件往里面放数据
if(f<0)
{
ERR_MSG("open file");
return -1;
}
while(1)
{
struct sockaddr_in ser;
socklen_t serlen = sizeof(ser);
datapag pg;
printf("1\n");
ssize_t len = recvfrom(cfd,&pg,sizeof(pg),0,(struct sockaddr *)&ser,&serlen);//获得数据包和服务器地址
if (len < 0)
{
ERR_MSG("recvfrom");
return -1;
}
a.block = pg.block;//修改ack的块编号
printf("2 %d\n",ntohs(a.block));
if(sendto(cfd,&a,sizeof(a),0,(struct sockaddr *)&ser,serlen) < 0)//发送ack
{
ERR_MSG("sendto");
return -1;
}
printf("3 %ld\n",len);
if(write(f,pg.data,len - 4) < 0)//往文件中写数据
{
ERR_MSG("write");
return -1;
}
if(len-4 < 512)//数据不足512则执行结束
{
puts("传输完成");
close(f);
return 0;
}
}
}
int main(int argc,const char *argv[])
{
//创建套接字
int cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd < 0)
{
ERR_MSG("socket");
return -1;
}
puts("socket success");
struct sockaddr_in addr;//服务器地址
addr.sin_family = AF_INET;
addr.sin_port = htons(69);
addr.sin_addr.s_addr = inet_addr(IP);
socklen_t addrlen = sizeof(addr);
char c = 0;
while(1)
{
puts("1.上传");
puts("2.下载");
puts("3.退出");
c = getchar();
while(getchar()!='\n');
if(c=='3')
break;
switch(c)
{
case '1':
break;
case '2':
download(cfd,&addr,addrlen);//下载函数
break;
}
}
//关闭文件
close(cfd);
return 0;
}