基于socket网络编程的文件传输程序

自己编写的用于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)),则文件虽然也可以传输成功,但传输的文件可能会出现问题。

代码比较简单,有不足之处或可改进的地方,欢迎大家提出意见。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值