网络编程day4作业

 下载和上传功能:

#include

//实现下载功能
int do_download(int cfd, struct sockaddr_in sin)
{
    //定义变量存储下载请求包
    char buf[516] = "";
    //定义变量存储文件名
    char fileName[40] = "";

    printf("请输入文件名:");
    scanf("%s", fileName);
    getchar();

    //组装请求包
    short *p1 = (short *)buf;
    *p1 = htons(1);                 //表明要下载

    char *p2 = buf+2;           //文件名段
    strcpy(p2, fileName);

    char *p4 = p2+strlen(p2)+1;    //模式段
    strcpy(p4, "octet");

    int size = 4 + strlen(p2) + strlen(p4);      //要发送数据的大小
    
    //向服务器发送下载请求
    if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("sendto error");
        return -1;
    }

    printf("请求成功\n");
/*********************************************/
    //循环接收回复服务器发来的消息
	//绑定客户端信息
/*	
	struct sockaddr_in cin1;
    cin1.sin_family = AF_INET;
    cin1.sin_port = htons(7788);
    cin1.sin_addr.s_addr = inet_addr("192.168.125.130");

	if(bind(cfd,(struct sockaddr*)&cin1,sizeof(cin1)) == -1)
	{
		perror("bind");
		return -1;
	}
	*/
	

	
	//定义临时地址结构体
	struct sockaddr_in sin1;
	/*
    sin1.sin_family = AF_INET;
    sin1.sin_port = htons(12345);
    sin1.sin_addr.s_addr = sin.sin_addr.s_addr;
	*/
	//创建文件
    int wfd = -1;
	if((wfd = open(fileName,O_WRONLY|O_CREAT|O_TRUNC,0664)) == -1)
	{
		perror("open");
		return -1;
	}


	int res = -1;
	while(1)
	{
		bzero(buf,sizeof(buf));
		socklen_t socklen = sizeof(sin1);
		res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin1,&socklen);
		if(buf[1] == 3)
		{
			write(wfd,buf+4,res-4);
		}
		if(res < 516)
		{
			printf("传输完成\n");
			break;
		}
		//返回一个ACK
		buf[1]=4;
		sendto(cfd,buf,4,0,(struct sockaddr*)&sin1,sizeof(sin1));

	}

}
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
//实现上传功能
int do_upload(int cfd, struct sockaddr_in sin)
{
    //定义变量存储上传请求包
    char buf[516] = "";
    //定义变量存储文件名
    char fileName[40] = "";

    printf("请输入文件名:");
    scanf("%s", fileName);
    getchar();

    //组装请求包
    short *p1 = (short *)buf;
    *p1 = htons(2);                 //表明要上传

    char *p2 = buf+2;           //文件名段
    strcpy(p2, fileName);

    char *p4 = p2+strlen(p2)+1;    //模式段
    strcpy(p4, "octet");

    int size = 4 + strlen(p2) + strlen(p4);      //要发送数据的大小
    
    //向服务器发送上传请求
    if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("sendto error");
        return -1;
    }

    printf("请求成功\n");
/*********************************************/
    //循环接收回复服务器发来的消息
	//绑定客户端信息
/*	
	struct sockaddr_in cin1;
    cin1.sin_family = AF_INET;
    cin1.sin_port = htons(7788);
    cin1.sin_addr.s_addr = inet_addr("192.168.125.130");

	if(bind(cfd,(struct sockaddr*)&cin1,sizeof(cin1)) == -1)
	{
		perror("bind");
		return -1;
	}
	*/
	

	
	//定义临时地址结构体
	struct sockaddr_in sin1;
	/*
    sin1.sin_family = AF_INET;
    sin1.sin_port = htons(12345);
    sin1.sin_addr.s_addr = sin.sin_addr.s_addr;
*/	
	//创建文件
    int wfd = -1;
	if((wfd = open(fileName,O_RDONLY)) == -1)
	{
		perror("open");
		return -1;
	}


	int res = -1;
	int count = 1;
	while(1)
	{
		//接受服务器返回来的ACK
		bzero(buf,sizeof(buf));
		socklen_t socklen = sizeof(sin1);
		recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin1,&socklen);
		//判断是否为ACK
		if(buf[1] == 4)
		{
			//组装有个数据包发送个服务器
			buf[1] = 3;
			buf[3] = count++;
			res = read(wfd,buf+4,sizeof(buf)-4);

			sendto(cfd,buf,res+4,0,(struct sockaddr*)&sin1,sizeof(sin1));

			if(res < 512)
			{
				printf("上传完成\n");
				break;
			}
		}
	}
}








int main(int argc, const char *argv[])
{
    if(argc != 2)
    {
        printf("input error\n");
        printf("usage:./a.out ip\n");
        return -1;
    }

    //1、创建套接字
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }

    //2、填充服务器地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(69);
    sin.sin_addr.s_addr = inet_addr(argv[1]);

    int mune = -1;
    while(1)
    {
        system("clear");                     //清屏
        printf("\t\t======1、下载=======\n");
        printf("\t\t======2、上传=======\n");
        printf("\t\t======0、退出=======\n");

        printf("请输入功能:");
        scanf("%d", &mune);
        getchar();

        //多分支选择
        switch(mune)
        {
        case 1:
            {
                do_download(cfd, sin);
            }
            break;

        case 2:
            {
                do_upload(cfd,sin);
            }
            break;
        case 0:
            goto POS;
        default:printf("输入功能有误,请重新输入\n");
        }

        //阻塞
        printf("输入任意键,按回车清空:");
        while(getchar() != '\n');

    }

POS:
    //关闭套接字
    close(cfd);


    return 0;
}

你可能感兴趣的:(网络)