TCP文件传送

本文介绍了通过TCP协议实现简单文件传输的过程。在服务器端,使用while循环读取文本文件并发送到客户端;客户端则接收数据并写入新文件,直到接收到的数据长度小于预期,表明文件传输完成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天看网络方面的东西,写了一个简单的文件传送的serve/client 的demo;能实现简单的文件传送. 用一个while循环来遍历整个文本文件,每次读到的数据,发送到客户端,在客户端,打开一个文件,每次读到数据后,写入文件,知道服务器端读到的数据长度小于其预定长度,则说明文件已经读完。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define   MAXLINE    1024
void my_err(const char *err_string,int line)
{
	fprintf(stderr,"line:%d",line);
	perror(err_string);
	exit(1);
}
int main(int argc,char *argv[])
{
	struct sockaddr_in  serv_addr;
	struct sockaddr_in  clie_addr;
	char buf[MAXLINE];
	int fp;
	int sock_fd;
	int  optval;
	int  link_fd;
	int recv_len;
	int write_len;
	int  clie_len;
	if(argc!=3)
	{
		printf("Usage:<可执行程序> <端口> <保存的文件名>\n");
		exit(0);
	}
	if((fp=open(argv[2],O_WRONLY | O_CREAT | O_EXCL,S_IRUSR | S_IWUSR))==-1)
	{
		my_err("open",__LINE__);
	}
	//创建一个TCP套接字
	if((sock_fd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		my_err("socket",__LINE__);
	}
	//设置该套接字使之可以重新绑定端口
	optval=1;
	if((setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval)))<0)
	{
		my_err("setsockopt",__LINE__);
	}
	//初始化
	memset(&serv_addr,0,sizeof(struct sockaddr_in));
	serv_addr.sin_family=AF_INET;
	serv_addr.sin_port  = htons(atoi(argv[1]));
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	//绑定
	if((bind(sock_fd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr_in)))<0)
	{
		my_err("bind",__LINE__);
	}
	//监听
	if((listen(sock_fd,5))<0)
	{
		my_err("listen",__LINE__);
	}
	while(1)
	{
		//通过accept接收客户端的连接请求,并返回连接套接字用于收发数据
		clie_len=sizeof(struct sockaddr_in);
	       link_fd=accept(sock_fd,(struct sockaddr *)&clie_addr,&clie_len);
	       if(link_fd<0)
	      {
		my_err("accept",__LINE__);
	      }
	
	       bzero(buf,MAXLINE);
	       while(recv_len = recv(link_fd,buf,MAXLINE,0))
	       {
		    if(recv_len <0)
	       	    {
			my_err("recv",__LINE__);
		    }  
	            write_len=write(fp,buf,recv_len);
	            if(write_len <recv_len)	
	            { 
		      my_err("write",__LINE__);
         	    }
	            bzero(buf,MAXLINE);
		}
		printf("接收文件完成!\n");
		close(fp);
		close(link_fd);
	}
	close(sock_fd);
	return 0;
}

2.client.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define MAXLINE  1024
void my_err(const char *err_string,int line)
{
	fprintf(stderr,"line:%d",line);
	perror(err_string);
	exit(1);
}
int main(int argc,char *argv[])
{
	struct sockaddr_in  clie_addr;
	char buf[MAXLINE];
	int sock_fd;
	int  fp;
	int conn_fd;
   	int read_len;
	int send_len;

if(argc!=4)
{
	printf("Usage:<可执行程序> <服务器地址> <端口> <文件名>");
}
if((fp=open(argv[3],O_RDONLY))<0)
{
	my_err("open",__LINE__);
}
//创建一个socket
if((sock_fd=socket(AF_INET,SOCK_STREAM,0))<0)
{
	my_err("socket",__LINE__);
}
//初始化
memset(&clie_addr,0,sizeof(struct sockaddr_in));
clie_addr.sin_family=AF_INET;
clie_addr.sin_port=htons(atoi(argv[2]));
if(inet_aton(argv[1],&clie_addr.sin_addr)<0)
{
	my_err("inet_aton",__LINE__);
}
//建立连接
conn_fd=connect(sock_fd,(struct sockaddr *)&clie_addr,sizeof(struct sockaddr));
if(conn_fd<0)
{
	my_err("connect",__LINE__);
}
bzero(buf,MAXLINE);
while((read_len=read(fp,buf,MAXLINE))>0)
{
	send_len=send(sock_fd,buf,read_len,0);
	if(send_len < 0)
	{
		my_err("send",__LINE__);
	}	
	bzero(buf,MAXLINE);
}
close(fp);
close(sock_fd);
printf("发送成功!\n");
return 0;
}

如果在两台电脑上,前提得连网在一台电脑上运行serve.c,在另外一台电脑上运行client.c,当然也可以在一台电脑上的两个终端上运行,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值