TCP编程实现文件下载基础模板可以参考:
程序原理:就是增加了文件的读写操作
TCP服务端代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SERVER_PORT 6666
#define BUFLEN 256
int setup_socket()
{
int ret = 0;
//1,创建SOCKET, 服务器的服务套接字
int server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock < 0)
{
perror("socket");
goto SOCKET_ERR;
}
//2, 填充服务器的地址信息
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//设置可以复用地址
int on = 1;
if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){
perror("setsockopt");
goto SOCKET_ERR;
}
//3,绑定
ret = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{
perror("bind");
goto SOCKET_ERR;
}
//4, 监听
ret = listen(server_sock, 5);
if(ret < 0)
{
perror("listen");
goto SOCKET_ERR;
}
return server_sock;
SOCKET_ERR:
return -1;
}
int main(int argc, char *argv[])
{
char buf[BUFLEN] = {0};
int client_sock = 0, ret = 0;
socklen_t addrlen = 0;
int server_sock;
struct sockaddr_in client_addr;
//SOCKADDR_IN client_addr;
FILE *srcFile = NULL; // 源文件
int numByte = 0; // 获取当前读取的字节数
int IsEnd = 1; //是否都取结束
int IsCloseServer = 1; //是否结束服务端程序
if(server_sock < 0)
{
perror("setup_socket");
goto SOCKET_ERR;
}
addrlen = sizeof(client_addr);
server_sock = setup_socket();
memset(&client_addr,0,sizeof(client_addr));
while(1)
{
memset(buf,0,BUFLEN);
//5, 接收连接
client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addrlen);
printf("accept connect form IP: %s, port:%d\n",
(char *)inet_ntoa(client_addr.sin_addr.s_addr) , ntohl(client_addr.sin_port));
//6, 读数据--接收文件名
ret = recv(client_sock, buf, BUFLEN, 0);
if(ret < 0)
{
perror("recv");
goto SOCKET_ERR;
}else if(ret == 0)
{
printf("recv cliet filename:%s %d\n", buf,ret);
}
printf("recv cliet filename:%s %d\n", buf,ret);
//判断当前目录下有没有该文件,以只读方式打开,没有则返回
srcFile = fopen(buf, "r");
if (NULL == srcFile) // 检查打开情况
{
perror(buf);
return -1;
}
memset(buf,0,BUFLEN);
//若存在该文件,则循环读取文件内容发送给客户端
while(IsEnd)
{
//printf("recv cliet filename:%s %d\n", buf,ret);
//从源文件中读取内容
numByte = fread(buf, 1, BUFLEN, srcFile);
if(feof(srcFile) && numByte == 0)
{
//服务器关闭了连接
//文件不存在
memset(buf,0,BUFLEN);
ret = send(client_sock, buf, numByte, 0);
IsEnd=0;
break;
}
//7, 发送文件内容数据
//bzero(buf, BUFLEN);
//strcpy(buf, "Hello World!\n");
ret = send(client_sock, buf, numByte, 0);
if(ret == 0)
{IsEnd=0;
//服务器关闭了连接
//文件不存在
memset(buf,0,BUFLEN);
ret = send(client_sock, buf, numByte, 0);
break;
}
memset(buf,0,BUFLEN);
}
//关闭打开的文件
fclose(srcFile);
//8,关闭连接
close(client_sock);
}
SOCKET_ERR:
return 0;
}
TCP客户端代码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SERVER_PORT 6666
#define BUFLEN 256
int main(int argc, char *argv[])
{
int ret = 0;
char buf[BUFLEN] = {0};
FILE *newFile = NULL; // 目标文件
int numByte = 0; // 获取当前读取的字节数
//1,创建socket
int client_sock = socket(AF_INET, SOCK_STREAM, 0);
if(client_sock < 0)
{
perror("socket");
goto SOCK_ERR;
}
//2,填充充服务器的地址信息
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
//3,连接服务器
ret = connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{
perror("connect");
goto SOCK_ERR;
}
memset(buf,0,BUFLEN);
//4,发送数据
//strcpy(buf, "I am a client\n"); //发送文件名给服务器
if(argc == 3)//一个个参数 需要下载的文件及路径, 第二个参数存储文件路径及新的文件名
{
strcpy(buf,argv[1]); //发送文件名给服务器
ret = send(client_sock, buf, strlen(buf), 0);
if(ret < 0)
{
perror("send");
goto SOCK_ERR;
}
}else
{
printf("请输入正确的需要下载的文件信息\n");
return 0;
}
//5,接收数据
memset(buf,0,BUFLEN);
ret = recv(client_sock, buf, BUFLEN, 0);
if(ret < 0)
{
perror("recv");
goto SOCK_ERR;
}
else if(ret == 0)
{
return 0;
//服务器关闭了连接
//文件不存在
}
newFile = fopen(argv[2],"w");
if (NULL == newFile)
{
perror("2.txt");
return -1;
}
//bzero(buf, BUFLEN);
while(1)
{
//把buf中的内容写到文件中
//write(fd, buf,....)
//把从源文件读取到的容写入到目标文件中
fwrite(buf,ret,1, newFile);
memset(buf,0,BUFLEN);
ret = recv(client_sock, buf, BUFLEN, 0);
if(ret == 0)
{
//服务器关闭了连接
//文件不存在
break;
}
}
//关闭打开的文件
fclose(newFile);
printf("recv msg from server:%s\n", buf);
//6,关闭连接
close(client_sock);
SOCK_ERR:
return 0;
}