Linux C做的TCP文件传输的代码

来源:互联网 发布:易语言读取网页源码 编辑:程序博客网 时间:2024/06/13 03:28

简要介绍一下代码结构:

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 ,在内部进行错误处理,让主函数调用起来更简洁;另外还定义了一些常量如服务器端口号和应用层缓冲区大小。

 

此代码实现的协议很简单,不过由于用的LINUXSOCKET实现,不能运行在WINDOWS上,不过说要是能做出对应projectWINDOWS版本,那么就完成了协议的跨平台实现,LINUXWIN也可以互相传文件了;不过我不熟悉WINDOWSWINSOCK的调用,谁能做出来的话,能把代码给我吗?万分感激!

 

。。。。。。。。

代码格式都变了,汗!居然不让我在前面放空格。

要看的人可以用 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;

}

common/common.h

 

#ifndef _COMMON_H

#define _COMMON_H

 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/socket.h>

#include <netinet/in.h>

 

#include <string.h>

#include <arpa/inet.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <signal.h>

#include <fcntl.h>

 

#define LISTENQ 20

#define MAXLINE 40

#define BUFFERSIZE 4096

#define PORT 50000

 

ssize_t writen(int fd, const void * vptr, size_t n);

ssize_t readline(int fd, void * vptr, size_t maxlen);

 

//wrappers

 

int Socket(int domain, int type, int protocol);

int Accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen);

int Inet_pton(int af, const char *src, void *dst);

int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

int Listen(int sockfd, int backlog);

int Close(int fd);

sig_t Signal(int signum, sig_t handler);

 

#endif

 

__________________________________________________________

 

common.c

 

#include "common.h"

 

ssize_t writen(int fd, const void * vptr, size_t n)

{

size_t    nleft;

ssize_t    nwritten;

const char *    ptr;

 

ptr = vptr;

nleft = n;

while (nleft > 0) {

if ((nwritten = write(fd, ptr, nleft)) <= 0) {

if (nwritten < 0 && errno == EINTR) {

nwritten = 0;

} else {

return -1;

}

}

 

nleft -= nwritten;

ptr += nwritten;

}

 

return n;

}

 

ssize_t readline(int fd, void * vptr, size_t maxlen)

{

ssize_t    n, rc;

char    c, *ptr;

 

ptr = vptr;

for (n = 1; n < maxlen; n++) {

again:

if ((rc = read(fd, &c, 1)) == 1) {

*ptr++ = c;

if (c == '/n') {

break;

}

} else if (rc == 0) {    /* EOF */

*ptr = 0;

return (n - 1);

} else {

if (errno == EINTR) {

goto again;

}

return (-1);

}

}

 

*ptr = 0;

return (n);

}

 

int Socket(int domain, int type, int protocol)

{

int sockfd;

if ((sockfd = socket(domain, type, protocol)) < 0) {

fprintf(stderr, "socket error/n");

exit(1);

}

 

return sockfd;

}

 

int Accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen)

{

int ret;

if ((ret = accept(sockfd, addr, addrlen)) < 0) {

fprintf(stderr, "accept error/n");

exit(1);

}

 

return ret;

}

 

int Inet_pton(int af, const char *src, void *dst)

{

int ret;

if ((ret = inet_pton(af, src, dst)) < 0) {

fprintf(stderr, "inet_pton error for %s/n", src);

exit(1);

}

 

return ret;

}

 

int Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

{

int ret;

if ((ret = connect(sockfd, addr, addrlen)) < 0) {

fprintf(stderr, "connect error/n");

exit(1);

}

 

return ret;

}

 

int Bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

{

int ret;

if ((ret = bind(sockfd, addr, addrlen)) < 0) {

fprintf(stderr, "bind error/n");

exit(1);

}

 

return ret;

}

 

int Listen(int sockfd, int backlog)

{

int ret;

if ((ret = listen(sockfd, backlog)) < 0) {

fprintf(stderr, "listen error/n");

exit(1);

}

 

return ret;

}

 

int Close(int fd)

{

int ret;

if ((ret = close(fd)) < 0) {

fprintf(stderr, "close error/n");

exit(1);

}

 

return ret;

}

 

sig_t Signal(int signum, sig_t handler)

{

struct sigaction act, oact;

 

act.sa_handler = handler;

sigemptyset(&act.sa_mask);

act.sa_flags = 0;

 

if (sigaction(signum, &act, &oact) < 0) {

return (SIG_ERR);

}

 

return (oact.sa_handler);

}

 

__________________________________________________________

 

Makefile

 

CC=gcc

PROG_NAME=fileclient fileserver    # ELF文件

INCS=common/common.h

SRCS=fileclient.c fileserver.c    # C文件

 

# .c 文件到 .o 文件

OBJS=${SRCS:.c=.o}

 

# libs

LIBS=

# ---- 用户修改区域结束

 

# _________________________________________________

 

all:${PROG_NAME}

 

fileclient:fileclient.o common/common.o

${CC} -o $@ $^

 

fileserver:fileserver.o common/common.o

${CC} -o $@ $^

 

# 如果有头文件进行修改,则自动编译源文件

${OBJS}:${INCS}

 

.c.o:

${CC} -c $< -Icommon

 

common/common.o:common/common.c common/common.h

cd common && ${CC} -c common.c

 

clean:

rm -f *.o ${PROG_NAME} common/*.o

 

rebuild:clean all

原创粉丝点击