由于需要服务器与客户端实现连接,需要建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。又为了让客户端能与服务器主机进行连接需要设置服务器IP地址和端口,初始化要绑定的网络地址结构,绑定IP地址、端口等信息,使用bind()函数,将套接字文件描述符和一个地址进行绑定实现客户端与服务器建立的套接字文件连接;然后接收客户端的数据,使用recvfrom()函数接收客户端的网络数据,且向客户端发送数据,使用sendto()函数向客户端发送数据。最后关闭套接字,使用close()函数释放资源。
?
#include<head.h>
#define PORT 69
#define Ip "192.168.122.88"
void xiazai(int sfd,struct sockaddr_in sin);
void shangchuan(int sfd,struct sockaddr_in sin);
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.填充服务器地址信息结构体
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(PORT);
sin.sin_addr.s_addr=inet_addr(Ip);
//3.选择下载、上传、退出
char ch;
while(1)
{
printf("\t 1、下载\n");
printf("\t 2、上传\n");
printf("\t 0、退出\n");
scanf("%c",&ch);
while(getchar()!=10);
switch(ch)
{
case '1':
xiazai(sfd,sin);
break;
case '2':
shangchuan(sfd,sin);
break;
case '0':
goto END;
break;
default:
printf("输入错误\n");
}
}
END:
close(sfd);
return 0;
}
//下载
void xiazai(int sfd,struct sockaddr_in sin)
{
char filename[20]="";
printf("请输入要下载的文件名>>");
fgets(filename,20,stdin);
filename[strlen(filename)-1]=0;
//发送下载请求
char buf[516]="";
short *p1=(short *)buf;
*p1=htons(1);
char *p2=buf+2;
strcpy(p2,filename);
char *p3=p2+strlen(p2)+1;
strcpy(p3,"octet");
int len = 4+strlen(p2)+strlen(p3);
int fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);//创建并打开文件
if(fd<0)
{
perror("open error");
return;
}
socklen_t socklen=sizeof(sin);
sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
while(1)
{
bzero(buf,sizeof(buf));
int rec=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);//接收数据包
if(buf[1]==3)
{
write(fd,buf+4,rec-4);
buf[1] = 4;
sendto(sfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin));//发送ACK
if(rec<516)
{
printf("下载完毕\n");
break;
}
}else if(buf[1]==5)
{
printf("ERROR:%s",buf+4);
break;
}
}
}
void shangchuan(int sfd,struct sockaddr_in sin)
{
char filename[20]="";
printf("请输入要上传的文件名>>");
fgets(filename,20,stdin);
filename[strlen(filename)-1]=0;
//发送上传请求
char buf[516]="";
short *p1=(short *)buf;
*p1=htons(2);
char *p2=buf+2;
strcpy(p2,filename);
char *p3=p2+strlen(p2)+1;
strcpy(p3,"octet");
int len = 4+strlen(p2)+strlen(p3);
socklen_t socklen=sizeof(sin);
int fd=open(filename,O_RDONLY);
if(fd==-1)
{
perror("open ERROR");
return;
}
sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
if(buf[1]==4)
{
int rec=read(fd,buf+4,sizeof(buf)-4);
buf[1] = 3;
sendto(sfd, buf, rec+4, 0, (struct sockaddr*)&sin, sizeof(sin));
if(rec==0)
{
printf("上传完毕\n");
break;
}
}
}
}
?
?