一个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;
}

________________________________________________________________________

相关推荐