#网络程序设计#实验二:利用TCP完成文件传输的设计和实现

更多网络程序设计的文章见:目录

实验目的

  • 输入文件路径,利用TCP实现客户文件向服务器的传输,并实现TCP的基本封装

实验原理

  • 服务器
    (1) 建立 socket
    (2) 确定服务器 scokaddr_in 结构体
    (3)点分十进制 IP 转换
    (4)使用 bind 绑定套接字
    (5)使用 listen 监听
    (6)使用 accept 接受连接请求
    (7)accept 返回新的套接字描述符
    (8)使用 recv 接收传来的数据(文件路径)
    (9)打开文件,这里需要文件名
    (10)从该字符串获取文件名
    (11)使用 recv 接收文件内容
    (12)判断 recv 函数返回的状态
    (13)将接收到的内容放入缓冲区
    (14)将缓冲区内容写入文件
    (15)关闭文件
    (16)关闭 socket
  • 客户端
    (1)建立 socket
    (2)确定服务器 scokaddr_in 结构体
    (3)点分十进制 IP 转换
    (4)使用 connect 连接
    (5)打开文件
    (6)准备缓冲区
    (7)缓冲区初始化置空
    (8)将文件内容读入缓冲区
    (9)使用 send 将缓冲区内容发送到服务器
    (10)文件内容发送完成(11)关闭文件
    (12)关闭 socket

实验内容

  • 服务器端
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
 
#define ERR_EXIT(m)				\
	do					\
	{					\
		perror(m);			\
		exit(EXIT_FAILURE);		\
	}while(0)
 
int passiveTCP()
{
	int listenfd;//创建一个套接字
	if((listenfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
	{
		ERR_EXIT("socket");
	}

	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(5188);
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);	
	
	if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
	{
		ERR_EXIT("bind");
	}
	
	if(listen(listenfd,SOMAXCONN) < 0)
		ERR_EXIT("listen");

	return listenfd;
}

int main()
{
	int fd = passiveTCP();
	char filename[100];
	char buffer[1024];

	while(1)
	{
		int conn;
		struct sockaddr_in peeraddr;
		socklen_t peerlen = sizeof(peeraddr);
		if((conn = accept(fd,(struct sockaddr*)&peeraddr,&peerlen)) < 0)
			ERR_EXIT("accept");
		else
		{
			printf("connect success\n");
			recv(conn, filename, sizeof(filename), 0);
			FILE *fp = fopen(filename, "w");
			printf("transport start\n");
			int t;
			while((t = recv(conn, buffer, 1024, 0)) > 0)
			{
				fwrite(buffer, sizeof(char), t, fp);
			}
			printf("transport finish\n");
			fclose(fp);
		}
		close(conn);
	}
	close(fd);
	return 0;
}
  • 客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#define ERR_EXIT(m)				\
	do					\
	{					\
		perror(m);			\
		exit(EXIT_FAILURE);		\
	}while(0)
 
int main()
{
	int sock;
	if((sock = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
	{
		ERR_EXIT("socket");
	}
	
	struct sockaddr_in servaddr;
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;	
	servaddr.sin_port = htons(5188);
	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	
	char filename [100];
	char buffer[1024];

	if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
		printf("error\n");
	else
	{
		printf("success\n");
		printf("input filename:\n");
		scanf("%s", filename);
		FILE* fp = fopen(filename, "r");
		if(fp == NULL)
			printf("file not exist\n");
		else
		{
			printf("transport start\n");
			send(sock, filename, sizeof(filename), 0);
			int t;
			while((t = fread(buffer, sizeof(char), 1024, fp)) > 0)
				send(sock, buffer, t, 0);
			printf("transport finish\n");
		}
		fclose(fp);
	}

	close(sock);
	return 0;
}

实验结果

  • 传输前客户端根目录下保存着文件1.txt
    在这里插入图片描述
  • 服务器根目录下没有这个文件
    在这里插入图片描述
  • 传输开始
    在这里插入图片描述
  • 传输完成后,服务器根目录下出现1.txt,传输成功
    在这里插入图片描述
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值