自己编写的用于linux下的简单文件传输程序,,传输模式为二进制,只可用于文件传输,分为客户端和服务器端,运行时先执行服务器端程序,再执行客户端程序,注意服务器端和客户端的文件名要在代码中修改。运行时直接输入./server和./client,不需要输入任何参数。
代码如下:
服务器端
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include<stdlib.h>
#include<string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define LISTENQ 20
#define PORT 8888
int main(int argc, char *argv[])
{
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sockfd, acceptfd;
unsigned char *buffer;
socklen_t sin_size;
int fd, n;
if(argc!=1)
{
fprintf(stderr, "Usage: %sportnumber\a\n", argv[0]);
exit(1);
}
/* 服务器端开始建立 socket 描述符 */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "Socketerror:%s\n\a", strerror(errno));
exit(1);
}
/* 服务器端填充 sockaddr 结构 */
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
/* 将server_addr结构绑定到sockfd */
if(bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr)) == -1)
{
//fprintf(stderr, "bind error: %s \n", strerror(errno));
fprintf(stderr, "bind error: %s\n", strerror(errno));
exit(1);
}
printf("bind port success.\n");
/* 监听端口,等待客户端的连接 */
if(listen(sockfd, LISTENQ) == -1)
{
fprintf(stderr, "listen error: %s \n", strerror(errno));
exit(1);
}
printf("server is listenning...\n");
sin_size = sizeof(struct sockaddr_in);
/* 接受客户端连接 */
if((acceptfd = accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size)) == -1)
{
fprintf(stderr, "accept error: %s \n", strerror(errno));
exit(1);
}
printf("success accept the link of client.\n");
//unsigned char *buffer = (unsigned char *)malloc(8192);//2*2048*500);
/* 申请分配8192个字节的内存空间 */
buffer = (unsigned char *)malloc(8192);
if(buffer)
printf("Memory Allocated at: %x\n",buffer);
else
{
printf("Not Enough Memory! Malloc error! \n");
return -1;//goto err_ret;
}
//fd = fopen("/home/ddrdate", "wb");
/* 打开/home下名为u-boot-xlnx-xilinx-v2014.4.tar.gz的文件(此处实为创建一个空的文件) */
fd = open("/home/test/u-boot-xlnx-xilinx-v2014.4.tar.gz", O_RDWR | O_CREAT); //上位机文件存储位置
printf("fd = %d \n", fd);
while(1)
{
volatile int wr_len;
//if(read(acceptfd, buffer, sizeof(buffer)) == -1)
/* 从acceptfd读取数据到buffer中 */
if((n = recv(acceptfd, buffer, sizeof(buffer), 0)) == 0) //sizeof(buff), 0) ==0)
{
printf("read over.\n");//printf(stderr, "read error: %s \n", strerror(errno));
break;//exit(1):
}
//else
//printf("read date success.\n");
//if((wr_len = fwrite(buff, sizeof(buff), 1, fd) ==0)
/* 将数据写到文件句柄fd中 */
if((wr_len = write(fd, buffer, n)) == -1)
{
fprintf(stderr, "write to /home/ddrdate.bin error: %s \n", strerror(errno));
break;//exit(1);
}
else
printf("write data: %d \n", wr_len);
}
free(buffer);
close(acceptfd);
close(sockfd);
return 0;
}
客户端
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include<stdlib.h>
#include<string.h>
/* 与服务器端建立连接 */
int CreateSock(char *destip, int port) /* destip为服务器端IP,port为其端口 */
{
//int port = atoi(destport);
int connectfd;
/* 创建套接字,使用TCP协议 */
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
printf("sockfd=%d\n", sockfd);
/* 客户端填充服务器端信息 */
struct sockaddr_in saddr;
bzero(&saddr, sizeof(struct sockaddr_in)); /* 清空地址结构*/
saddr.sin_family = AF_INET; /* 使用IPV4通信域 */
saddr.sin_port = htons(port); /* 端口号转换为网络字节序 */
inet_pton(AF_INET,destip,&saddr.sin_addr.s_addr); /* 将“点分十进制”的IP地址转换为“整数” */
/* 主动连接服务器 */
if((connectfd = connect(sockfd, (struct sockaddr*)(&saddr), sizeof(saddr)))<0)
{
perror("connect");
printf("connect error! stop send!\n");
exit(1);
}
printf("connectfd=%d\n", connectfd);
//close(sockfd);
return sockfd;//connectfd;
}
int retr(int connfd)
{
//int fd;
FILE *fd;
int n;
char buf[BUFSIZ];
volatile int len;
//if((fd=open("/home/READ.txt", O_RDWR)) == -1)
/* 打开/home下的u-boot-xlnx-xilinx-v2014.4.tar.gz文件,返回其句柄 */
if((fd=fopen("/home/u-boot-xlnx-xilinx-v2014.4.tar.gz", "rb")) == NULL)
{
printf("open file error.\n");
return -1;
}
else
printf("open file success.\n");
while(1)
{
//if(read(fd, buf, sizeof(buf)) == 0)
/* 从fd读8192个字节数据到buf中 */
if((n = fread(buf, 1, 8192, fd)) == 0) //fd -> buf
{
fprintf(stderr,"fread error or over: %s\n", strerror(errno));
break;
}
/*{
printf("read error or over.\n");
break;
}
*/
//if((len = write(connfd, buf, sizeof(buf))) == 0)
printf("connfd=%d\n", connfd);
/* 将buf中数据发送到连接套接字connfd */
if((len = send(connfd, buf, n, 0)) == -1)
{
fprintf(stderr, "send error: %s\n", strerror(errno));
break;
}
printf("send data: %d \n", len);
}
close(connfd);
fclose(fd);
}
int main()
{
int connfd;
connfd = CreateSock("10.8.248.159", 8888);
printf("main connfd = %d\n", connfd);
retr(connfd);
return 0;
}
这里要注意的一个地方是,服务器端的程序中write()函数的第三个参数应为recv的返回值n,若为其他值如write(fd, buffer, sizeof(buffer)),则文件虽然也可以传输成功,但传输的文件可能会出现问题。
代码比较简单,有不足之处或可改进的地方,欢迎大家提出意见。