TCP服务端和TCP客户端编程,完成文件传输(客户端输入文件名,服务端接收文件数据并保存至服务端本地)
此文件是在Linux系统运行的,Windows中不包含socket等头文件
可以传输大型文件,其基本思想为把文件名字读出来放到filename数组中,然后copy到buffer中,接着将独到的文件内容接在buffer数组中文件名称后面。然后循环读取,以后每次将独到的数据放入buffer传输。
反之服务端解析也一样。
关于用到的函数可以通过查询C 语言教程
关于头文件可以参考socket编程中用到的头文件
下面是客户端端的代码
client.c
/*
TCP客户端,发送文件
客户端输入文件名,服务端接收数据并保存至服务端本地
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define IP_ADDRESS "127.0.0.1"
#define SERV_PORT 1234
#define BUFFER 1024
#define FILE_NAME 128
int main() {
int clnt_sock = socket(AF_INET, SOCK_STREAM, 0); //1.创建套接字
if (clnt_sock < 0) {
perror("error");
return 1;
}
struct sockaddr_in clnt_addr;
memset(&clnt_addr, 0, sizeof(clnt_addr));
//将套接字和IP,端口绑定
clnt_addr.sin_family = AF_INET;
clnt_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
clnt_addr.sin_port = htons(SERV_PORT);
int ret = connect(clnt_sock, (struct sockaddr *)&clnt_sock, sizeof(clnt_addr)); //2,连接到计算机制定端口
if (ret < 0) {
perror("error");
return 1;
}
char buffer[BUFFER];
memset(buffer, 0, BUFFER);
char filename[FILE_NAME];
printf("连接成功,请输入要发送的文件名称:");
scanf("%s", filename);
FILE *fp;
fp = fopen(filename, "r");
memcpy(buffer, filename, FILE_NAME);
fread(buffer + FILE_NAME, sizeof(char), BUFFER - FILE_NAME, fp);
printf("发送内容为:\n");
int ret1 = 1;
int x = 0;
while (ret1 < 0) {
ret = send(clnt_sock, buffer, BUFFER, 0); //3 向socket中写入信息
if (ret < 0) {
printf("senf fail!\n");
break;
}
printf("%s", buffer);
memset(buffer, 0, BUFFER);
ret1 = fread(buffer, sizeof(char), BUFFER, fp);
}
fclose(fp);
close(clnt_sock); //4,关闭socket
return 0;
}
下面是服务端代码
server.c
/*
TCP客户端,接收文件
客户端输入文件名,服务端接收数据并保存至服务端本地
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define IP_ADDRESS "127.0.0.1" //ip地址
#define SERV_PORT 1234 //端口号
#define BUFFER 1024 //存放临时数据的buffer大小
#define FILE_NAME 128 //临时存放文件名称的数组大小
int main() {
int serv_sock = socket(AF_INET, SOCK_STREAM, 0); //1.创建套接字
if (serv_sock < 0) {
perror("error");
return 1;
}
struct sockaddr_in serv_addr;
memset(&clnt_addr, 0, sizeof(clnt_addr));
//将套接字和IP,端口绑定
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
serv_addr.sin_port = htons(SERV_PORT);
int ret = connect(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); //2,绑定socket和端口号
if (ret < 0) {
perror("error");
return 1;
}
listen(serv_sock, 5); //3,监听端口号
struct sockaddr_in clnt_addr;
socklen_t len = sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr *)&serv_addr, &len); //4,等待接收客户端连接
if (clnt_sock < 0) {
perror("error");
return 1;
} else {
printf("accept success!");
}
char buffer[BUFFER];
memset(buffer, 0, BUFFER);
char filename[FILE_NAME];
printf("连接成功,请输入要发送的文件名称:");
scanf("%s", filename);
FILE *fp;
int rd, x = 0; //x用于判断是不是第一次传过来的数据
while (rd = recv(clnt_sock, buffer, BUFFER, 0)) {
if (x == 0) { //x=0表示是第一次传过来的数据,其中包含文件名称和文件内容
strncpy(filename, buffer, FILE_NAME);
fp = fopen(filename, "w+");
fwrite(buffer + FILE_NAME, sizeof(char), BUFFER - FILE_NAME, fp);
x = 1; //置1后表示以后的数据不是第一次进来的,其中只有文件内容。
} else {
if (rd <= 0) {
printf("客户端掉线!");
break;
}
fwrite(buffer, sizeof(char), BUFFER, fp);
}
printf("%s", buffer);
memset(buffer, 0, BUFFER);
}
fclose(fp);
close(clnt_sock);
close(serv_sock); //4,关闭socket
return 0;
}