一个Linux C做的TCP文件传输的代码
贴一个Linux C做的TCP文件传输的代码
简要介绍一下代码结构:
~project-----------fileclient.c
~ |-----------fileserver.c
~ |-----------Makefile
~ |-----------common-----------common.c
~ |-----------common.h
编译方法: 进入project目录,make(有兴趣的话可以看看我的Makefile,其实写的不通用)
使用方法: 接收端运行 ./fileserver
发送端运行 ./fileclient <localfile> <serverIP>
如果谁愿意读此代码,请重点读fileserver.c 和 fileclient.c ,通信交互部分我用
"///// communication part /////"的方式隔开了, common 目录下的 common.h 主要定义了一些wrapper functions ,在内部进行错误处理,让主函数调用起来更简洁;另外还定义了一些常量如服务器端口号和应用层缓冲区大小。
此代码实现的协议很简单,不过由于用的LINUX的SOCKET实现,不能运行在WINDOWS上,不过说要是能做出对应project的WINDOWS版本,那么就完成了协议的跨平台实现,LINUX和WIN也可以互相传文件了;不过我不熟悉WINDOWS和WINSOCK的调用,谁能做出来的话,能把代码给我吗?万分感激!
。。。。。。。。
代码格式都变了,汗!居然不让我在前面放空格。
要看的人可以用 indent -kr <cfile>来格式化一下。(前提是要装indent)
fileclient.c
#include "common/common.h"
int main(int argc, char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: ./fileclient <file> <serverIP>\n");
exit(1);
}
int sockfd;
char buff[BUFFERSIZE + 1];
char filenameheader[BUFFERSIZE + 1];
struct sockaddr_in servaddr;
int filefd; /* file descriptor */
int count;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
Inet_pton(AF_INET, argv[2], &servaddr.sin_addr);
servaddr.sin_port = htons(PORT);
//////////////////////////////////////////////////////////
printf("connecting........\n");
Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
printf("transferring file name: %s........\n", argv[1]);
memcpy(filenameheader, argv[1], strlen(argv[1]));
filenameheader[strlen(argv[1])] = '\n';
filenameheader[strlen(argv[1]) + 1] = 0;
writen(sockfd, filenameheader, strlen(filenameheader));
printf("will transfer file: %s\n", argv[1]);
filefd = open(argv[1], O_RDONLY);
if (filefd < 0) {
fprintf(stderr, "can't open the file: %s\n", argv[1]);
exit(1);
}
while(count = read(filefd, buff, BUFFERSIZE)) {
if (count < 0) {
fprintf(stderr, "filefd read error\n");
exit(1);
}
if (writen(sockfd, buff, count) < 0) {
fprintf(stderr, "writing to sockfd error\n");
exit(1);
}
}
Close(filefd);
Close(sockfd);
printf("file %s transferred!\n", argv[1]);
//////////////////////////////////////////////////////////
return 0;
}
______________________________________________________________________-
fileserver.c
#include "common/common.h"
int main(void)
{
int listenfd, connfd;
char buff[BUFFERSIZE + 1];
char filename[BUFFERSIZE + 1];
struct sockaddr_in servaddr, cliaddr;
int cliaddrlen;
int filefd; /* file descriptor */
int count;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
//////////////////////////////////////////////////////////
while(1) {
printf("listening........\n");
cliaddrlen = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
printf("readinging filename........\n");
if (readline(connfd, buff, BUFFERSIZE) < 0) {
fprintf(stderr, "readline error\n");
exit(1);
}
buff[strlen(buff) - 1] = 0; /* change '\n' to NUL */
memcpy(filename, buff, BUFFERSIZE + 1);
printf("will save to file: %s\n", buff);
filefd = open(buff, O_WRONLY | O_CREAT);
if (filefd < 0) {
fprintf(stderr, "can't open the file: %s\n", buff);
exit(1);
}
while(count = read(connfd, buff, BUFFERSIZE)) {
if (count < 0) {
fprintf(stderr, "connfd read error\n");
exit(1);
}
if (writen(filefd, buff, count) < 0) {
fprintf(stderr, "writing to filefd error\n");
exit(1);
}
}
Close(filefd);
Close(connfd);
printf("file %s received!\n", filename);
}
Close(listenfd);
//////////////////////////////////////////////////////////
return 0;
}
________________________________________________________________________