简单文件传输(socket)

该代码示例展示了一个简单的文件传输服务端和客户端程序,使用C语言编写。服务端监听8888端口,接收客户端请求,根据get命令发送文件大小信息及文件内容。客户端连接服务端,输入文件名请求文件并接收文件数据。

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

1、服务器

main.c

#include "mynet.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

int main()
{
	int ser_fd = init_net();
	if(ser_fd < 0)
	{
		puts("init_net error.");
		return -1;
	}
	int connfd = -1;
	struct sockaddr_in mycli;
	int len = sizeof(mycli);
	connfd = accept(ser_fd, (struct sockaddr *)&mycli, &len);
	if(connfd < 0)
	{
		puts("accept error.");
		close(ser_fd);
		return -1;
	}
	puts("accept success.");
	do_work(connfd);
	close(ser_fd);
	return 0;
}

mynet.h

#ifndef __MYNET_H__
#define __MYNET_H__
	int init_net();
	int do_work(int connfd);
	int get_file_name(char *filename, char *cmd);
	int get_req(char *myreq, char *cmd);
	int get_file_len(int fd);
#endif

mynet.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int init_net()
{
	int ser_fd = -1;
	//socket
	ser_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(ser_fd < 0)
	{
		puts("socket error.");
		return ser_fd;
	}
	puts("socket success.");
	//bind
	struct sockaddr_in myser;
	memset(&myser, 0, sizeof(myser));
	myser.sin_family = AF_INET;
	myser.sin_port = htons(8888);
	myser.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(ser_fd, (struct sockaddr *)&myser, sizeof(myser));
	if(ret != 0)
	{
		puts("bind error.");
		close(ser_fd);
		ser_fd = -1;
		return ser_fd;
	}
	puts("bind success.");
	//listen
	ret = listen(ser_fd, 5);
	if(ret != 0)
	{
		puts("listen error.");
		close(ser_fd);
		ser_fd = -1;
		return ser_fd;
	}
	puts("listen success.");
	return ser_fd;
}

int get_file_name(char *filename, char *cmd)
{
	if(NULL == filename && NULL == cmd)
	{
		puts("get_file_name:error.");
		return -1;
	}
	
	char *p = cmd+4;
	int len = strlen(cmd);
	cmd[len-1] = 0;
	strcpy(filename, p);
	return 0;
}

int get_req(char *myreq, char *cmd)
{
	if(NULL == myreq && NULL == cmd)
	{
		puts("get_req:error.");
		return -1;
	}
	
	char *p = cmd;
	int i = 0;
	while(*p != ' ')
	{
		myreq[i] = *p;
		i++;
		p++;
	}
	myreq[i] = 0;
	return 0;
}

int get_file_len(int fd)
{
	if(fd < 0)
	{
		puts("get file len error.");
		return -1;
	}
	int len = lseek(fd, 0, SEEK_SET);
	len = lseek(fd, 0, SEEK_END);
	return len;
}

int do_work(int connfd)
{
	if(connfd < 0)
	{
		puts("connfd < 0");
		return -1;
	}
	puts("do_work");
	char cmd[50];
	memset(cmd, 0, sizeof(cmd));
	int ret = recv(connfd, cmd, sizeof(cmd), 0);
	if(ret > 0)
	{
		//puts(cmd);
		char filename[40] = {0};
		get_file_name(filename,cmd);
		puts(filename);
		char req[5] = {0};
		get_req(req,cmd);
		puts(req);
		if(strcmp(req,"get") == 0)
		{
			int fd = open(filename, O_RDONLY);
			if(fd < 0)
			{
				puts("get file not exist.");
				return -1;
			}
			int len = get_file_len(fd);
			char filelen[20] = {0};
			sprintf(filelen,"len:%d",len);
			puts(filelen);
			send(connfd, filelen, 20, 0);

			char *pcon = NULL;
			pcon = (char *)malloc(len);
			memset(pcon, 0, len);
			lseek(fd, 0, SEEK_SET);
			int ret = read(fd, pcon, len);
			if(ret == len)
			{
				send(connfd, pcon, len, 0);
			}
			free(pcon);
			close(fd);
		}
	}
	return 0;
}

2、客户端

main.c

#include "mycli.h"
#include <unistd.h>

int main()
{
	int mysock = mycli_init("192.168.1.13", 8888);
	if(mysock > 0)
	{
		do_work(mysock);
		close(mysock);
		return 0;
	}
}

mynet.h

#ifndef __MYCLI_H__
#define __MYCLI_H__
	int mycli_init(char *ip, unsigned short port);
	int do_work(int connfd);
#endif

mynet.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>

int mycli_init(char *ip, unsigned short port)
{
	if(NULL == ip)
	{
		puts("ip is null");
		return -1;
	}
	int myfd = -1;
	//socket
	myfd = socket(AF_INET, SOCK_STREAM, 0);
	if(myfd < 0)
	{
		puts("socket error.");
		return myfd;
	}
	puts("socket success.");
	//connect
	struct sockaddr_in myser;
	memset(&myser,0,sizeof(myser));
	myser.sin_family = AF_INET;
	myser.sin_port = htons(port);
	myser.sin_addr.s_addr = inet_addr(ip);
	int ret = connect(myfd, (struct sockaddr *)&myser, sizeof(myser));
	if(ret != 0)
	{
		puts("connect error.");
		close(myfd);
		myfd = -1;
		return myfd;
	}
	puts("connect success.");
	return myfd;
}

int do_work(int connfd)
{
	if(connfd < 0)
	{
		puts("connfd < 0");
		return -1;
	}
	puts("do_work");
	char buf[50];
	memset(buf, 0, sizeof(buf));
	fgets(buf,sizeof(buf),stdin);
	char fn[30]={0};
	strcpy(fn, buf+4);
	fn[strlen(fn)-1]=0;
	send(connfd, buf, sizeof(buf), 0);
	memset(buf, 0, sizeof(buf));
	int ret = recv(connfd, buf, 20, 0);
	if(ret >0)
	{
		puts(buf);
		int len = atoi(buf+4);
		printf("len is %d\n",len);
		int total = len;
		char *pcon = NULL;
		pcon = (char *)malloc(len);
		memset(pcon,0,len);
		int fd = open(fn,O_WRONLY | O_CREAT, 0664);
		if(fd < 0)
		{
			return -1;
		}
		while(total)
		{
			ret = recv(connfd, pcon, total, 0);
			if(ret > 0)
			{
				write(fd, pcon, ret);
				total -= ret;
			}
		}
		free(pcon);
		close(fd);
	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值