#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define MSG_ERR(msg) do{\
printf("%d\n",__LINE__);\
perror(msg);}\
while(0)
#define PORT 69
#define IP "192.168.8.166"
int downloadfile(int sfd ,struct sockaddr_in sin);
int uploadfile(int sfd ,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
//创建数据报式管道文件
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd<0)
{
MSG_ERR("socket");
return -1;
}
//发送到的服务器基本地址信息
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(PORT);
sin.sin_addr.s_addr=inet_addr(IP);
socklen_t addrlen=sizeof(sin);
char c;
while(1)
{
//system("clear");
printf("输入 1 下载文件\n");
printf("输入 2 上传文件\n");
printf("输入 3 退出客户端\n");
printf("请输入>>>");
c=getchar();
while(getchar()!=10);
switch(c)
{
case'1':downloadfile(sfd,sin);
break;
case '2':
uploadfile(sfd,sin);
break;
case '3':
goto end;
break;
}
}
end:
close(sfd);
return 0;
}
int downloadfile(int sfd ,struct sockaddr_in sin)
{
//发送数据
char buf[516]="";
char filename[50]="";
printf("请输入从服务器中下载的文件名");
fgets(filename,sizeof(filename),stdin);
filename[strlen(filename)-1]=0;
short *p1=(short *)buf;
*p1=htons(1);
char *p2=buf+2;
strcat(p2,filename);
char *p3=p2+strlen(filename);
*p3=0;
char *p4=p3+1;
strcat(p4,"octet");
// sprintf(buf,"%c%c%s%c%s%c",0,1,filenmae,0,octet,0);
int n=2+strlen(filename)+1+5+1;
if(sendto(sfd,buf,n,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
MSG_ERR("sendto");
}
printf("发送成功\n");
int flag=0;
int fd=-1;
int num=1;
//接受数据包
bzero(buf,sizeof(buf));
struct sockaddr_in bin;
socklen_t addrlen_bin=sizeof(bin);
while(1)
{
ssize_t rcv;
rcv=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&bin,&addrlen_bin);
if(rcv<0)
{
MSG_ERR("recv");
return -1;
}
if(rcv==0)
{
printf("对方服务器关闭\n");
break;
}
if(3==buf[1])
{
printf("接收到的是数据包\n");
short *block_num=(short *)&buf+1;
if(num==ntohs(*block_num))
{
num++;
if(flag==0)
{
fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
if(fd<0)
{
MSG_ERR("open");
}
flag=1;
}
//解析数据包
printf("块编号%d\n",ntohs(*block_num));
if (write(fd,buf+4,rcv-4)<0)
{
MSG_ERR("fwrite");
return -1;
}
//发送ACK
// fprintf("buf,%c%c%c%c",0,4,0,3);
/* short *a1=(short*)buf;
*a1=htons(4); */
buf[1]=4;
int count_ack=4;
if(sendto(sfd,buf,count_ack,0,(struct sockaddr*)&bin,sizeof(bin))<0)
{
MSG_ERR("sendto");
return -1;
}
printf("发送ASK成功\n");
if(rcv<516)
{
printf("下载成功\n");
break;
}
}
}
else if(5==buf[1])
{
printf("接收到的是ERROR\n");
//解析错误包
short *err_num=(short *)buf+1;
char* err_data=buf+4;
printf("差错码%d\n",ntohs(*err_num));
if (fputs(err_data,stdout)<0)
{
MSG_ERR("fputs");
return -1;
}
break;
}
}
close(fd);
return 0;
}
int uploadfile(int sfd ,struct sockaddr_in sin)
{
//发送请求数据
char buf[516]="";
char filename[50]="";
printf("请输入上传到服务器的文件名");
fgets(filename,sizeof(filename),stdin);
filename[strlen(filename)-1]=0;
short *p1=(short *)buf;
*p1=htons(2);
char *p2=buf+2;
strcat(p2,filename);
char *p3=p2+strlen(filename);
//*p3=0;
char *p4=p3+1;
strcat(p4,"octet");
// sprintf(buf,"%c%c%s%c%s%c",0,1,filenmae,0,octet,0);
int n=2+strlen(filename)+1+5+1;
if(sendto(sfd,buf,n,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
MSG_ERR("sendto");
}
printf("上传请求发送成功\n");
bzero(buf,sizeof(buf));
struct sockaddr_in bin;
socklen_t addrlen_bin=sizeof(bin);
ssize_t nbytes=0;
int num=1;
int fd=-1;
int flag=0;
ssize_t rcv;
while(1)
{
//接受ask包
rcv=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&bin,&addrlen_bin);
if(rcv<0)
{
MSG_ERR("recv");
return -1;
}
if(rcv==0)
{
printf("对方服务器关闭\n");
break;
}
short *s_num=(short *)buf;
printf("操作码%d\n",ntohs(*s_num));
short *block_num=(short *)buf+1;
printf("块编号%d\n",ntohs(*block_num));
if (buf[1]==4)
{
//发送数据包
if(flag==0)
{
fd=open(filename,O_RDONLY);
if(fd<0)
{
MSG_ERR("open");
}
flag=1;
}
buf[1]=3;
buf[3]=num;
num++;
nbytes=read(fd,buf+4,512);
printf("%s",buf+4);
if(nbytes<0)
{
MSG_ERR("read");
return -1;
}
if(sendto(sfd,buf,nbytes+4,0,(struct sockaddr*)&bin,sizeof(bin))<0)
{
MSG_ERR("sendto");
return -1;
}
printf("发送数据包成功\n");
if(nbytes<512)
{
printf("上传成功\n");
break;
}
}
//解析错误包
if(5==buf[1])
{
printf("接收到的是ERROR\n");
short *err_num=(short *)buf+1;
char* err_data=buf+4;
printf("差错码%d\n",ntohs(*err_num));
if (fputs(err_data,stdout)<0)
{
MSG_ERR("fputs");
break;
}
}
}
close(fd);
return 0;
}
TCCP协议服务器的上传和下载
最新推荐文章于 2024-08-22 23:45:07 发布