linux socket 文件传输程序

本文介绍了一个基于TCP协议的简单文件传输系统,包括服务器端和客户端的设计与实现。服务器作为守护进程运行,监听指定端口;客户端需进行用户名密码验证后才能上传文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本程序说明:

 通过TCP协议实现简单文件传输,要求:
1.服务器端为一守护进程,端口号为10000
2.客户端在传输文件之前应该先输入用户名,密码认证。用户名,密码保存在文件/etc/login.txt文件中
  文件内容为(自己制造一文件为此格式):
  cat /etc/login.txt
  username:cuit_train
  passwd:Good_job
3.认证通过之后,客户端有几个选项,1.上传文件,需要sacnf文件绝对路径  2.退出

 

 

/**************server.c***************/

 

#include<stdio.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/time.h>
#include<sys/wait.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include "name.h"

#define MAXFILE 65535
#define MAXDATASIZE 1000  
#define BACKLOG 10            /*max connect*/
#define PORT 10000
#define PATH  "/etc/login.txt"


char buf[MAXDATASIZE];

 

void name(char *p);
void daemo();
void server();
int child_process(int connect);
int check_passwd(char *client_passwd);
int getpasswd(char *p_file_name, char *server_passwd);

int main(int argc, char **argv)
{
 pid_t pid;
 pid = fork();
 
 //  for  daemon      
 if(pid < 0)
 {
  perror("fork error");
  return 1;
 }
 else if(pid > 0)
  return 0;
 else    // daemo
 {
  daemo();
 }
 
 //server();
}

void daemo()
{
 int i;
 setsid();    /*frist*/
 chdir("/"); /*sencond*/
 umask(0);  /*thrid*/
 for(i = 0; i<MAXFILE; i++)
  close(i);
 server(); /*启动服务器程序*/                
}

/*the server */
void server()
{
 int listenfd, connectfd;
 struct sockaddr_in server, client;
 socklen_t addrlen;
 pid_t pid;
 if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 {
  perror("error socket");
  exit(1);
 }
 
 /*IP ADDRESS 重用*/
 int opt = 1;
 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

 bzero(&server, sizeof(server));
 server.sin_family = AF_INET;
 server.sin_port = htons(PORT);
 server.sin_addr.s_addr = htonl(INADDR_ANY);

 if((bind(listenfd, (struct sockaddr *)&server, sizeof(server))) == -1)
 {
  perror("error bind");
  exit(1);
 }
 if(listen(listenfd, BACKLOG) == -1)
 {
  perror("error listen");
  exit(1);
 }
 addrlen = sizeof(client);
 while(1)
 {
  if((connectfd = accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -1)
  {
   perror("error accetp");
   continue;
  }
  printf("you got a connection from client ip is: %s, port is:%d /n",
    inet_ntoa(client.sin_addr), ntohs(client.sin_port));
  
  /*fork*/
  pid = fork();
  if(pid < 0)
  {
   perror("fork error");
   continue;
  }
  else if(pid > 0)
  {
   close(connectfd);
   continue;
  }
  else
  {
   close(listenfd);
 
  /*call child_process function*/
   child_process(connectfd);
  } 
  
 } 
}


/*当收到一个客户的的联接后全由子进程处理一切*/
/*child process function*/
int child_process(int connectfd)
{
 FILE *fp;
 char t_file_name[100];
 char client_passwd[100];
 ssize_t ssize;
 ssize_t rsize;
 int check;
 int i;
 
 /*check passwd*/
 while(1)
 {
  bzero(client_passwd, sizeof(client_passwd));
  rsize = recv(connectfd, client_passwd, sizeof(client_passwd), 0);
  if(strncmp("exit", client_passwd, 4) == 0)
  { 
   printf("client exit, wait the next client call/n");
   close(connectfd);
   exit(0);
  }

  /*return 0 client passwd is right*/
  check = check_passwd(client_passwd);
  if(check == 0)
  {
   send(connectfd, "right", 6, 0);
   printf("client name and passwd is right/n");
   break;
  }
  else
   send(connectfd, "error", 6, 0);

 }

/*处理文件传送*/
 while(1)
 {  
  bzero(t_file_name, sizeof(t_file_name));
  rsize = recv(connectfd, t_file_name, sizeof(t_file_name), 0);
  /*判断客户是否推出*/
  if(strncmp("exit", t_file_name, 4) == 0)
  { 
   printf("client exit, wait the next client call/n");
   close(connectfd);
   exit(0);
  }

  /*find transmission file name,example client filename is "/root/a.log",
  the name function transmission fime name is "a.log" */
  name(t_file_name);
   
  fprintf(stdout, "receive file name is %s/n", t_file_name);
  if((fp = fopen(t_file_name, "w")) == NULL)
  {
   perror("cannot open file");
   return 1;
  }
   
  while(1)
  {
   bzero(buf, sizeof(buf));
   rsize = recv(connectfd, buf, MAXDATASIZE,0);
   if((strncmp(buf, "end", 3)) == 0)
   {
    printf("ok! receive over");
    break;
   }
   fwrite(buf, 1, rsize, fp);
   i++;
   printf("fwrite i = %d, rsoze = %d/n", i, rsize);
  }
  fclose(fp); 
 }
 close(connectfd); 
 
}

int getpasswd(char *p_file_name, char *server_passwd)
{
 int filefd;
 filefd = open(p_file_name, O_RDONLY);
 if(filefd == -1)
 {
  perror("error open");
  exit(1);
 }
 if((read(filefd, server_passwd, 18)) > 0)
 {
  //printf("server_passwd :%s/n", server_passwd);
  return 0;
 }
 else
  return -1;
}

/*return 0  client_passwd is right*/
int check_passwd(char *client_passwd)
{
 char server_passwd[100];
 bzero(server_passwd, sizeof(server_passwd));
 printf("the client_passwd is :%s/n", client_passwd);
 getpasswd(PATH, server_passwd);
 
 printf("server_passwd :%s/n", server_passwd);
 if((strncmp(server_passwd, client_passwd, strlen(server_passwd))) == 0)
  return 0;
 else
  return -1;
}

 

/*find transmission file name,example client filename is "/root/a.log",
  the name function transmission fime name is "a.log" */
void name(char *p)
{
 int len, i;
 len = strlen(p);
 for(i = len-1; i >= 0; i--)
 {
  if(p[i] == '/')
   break;
 }
 if(i>=0)
 {
  strcpy(p, p+i+1);
 }
}

 

 


////////////////////////////////////client,c////////////////////////////////

#include<stdio.h>
#include<unistd.h>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//#include"name.h"

#define PORT 10000
#define MAXDATASIZE (1024*1024)


int check_passwd(int sockfd);
int tra_file(int sockfd);
int main ( int argc, char *argv[])
{
 int sockfd;
 struct hostent *he;
 struct sockaddr_in server;
 char chose[20];

 if(argc!=2)
 {
  printf("usage %s<ip address>/n",argv[0]);
  exit(1); 
 }
 if((he = gethostbyname(argv[1])) == NULL)
 {
  printf("gethostbyname error/n");
  exit(1);
 }
 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
 {
  printf("socket() error /n");
  exit(1);
 }
 bzero(&server, sizeof(server));
 server.sin_family = AF_INET;
 server.sin_port = htons(PORT);
 server.sin_addr = *((struct in_addr *)he->h_addr);
 if(connect(sockfd, (struct sockaddr *)&server, sizeof(server)) == -1)
 {
  printf("connetc() error/n");
  exit(1);
 }
   
 /*验证密码和用户名*/
 check_passwd(sockfd);


 /*file tramsmission*/
 while(1)
 {
  printf("chose you want to do/n  chose '1' to tramsmission file, chose 'e' to exit/n");
  scanf("%s", chose);
  if(chose[0] == 'e')
  {
   send(sockfd, "exit", 5, 0);
   close(sockfd);
   exit(0);
  }
  else /*file tramsmission*/
  {
   tra_file(sockfd);
  } 
  
 }

 close(sockfd);
 return 0;  
}


/*验证正确才退出此函数*/
int check_passwd(int sockfd)
{
 char chose[20];
 char passwd[30];
 char client_passwd[100];
 char buf[MAXDATASIZE];
 while(1)
 {
  printf("########chose you want to do############/n");
  printf("***** chose '1' to check name and passwd, chose 'e' to exit***/n");
  scanf("%s", chose);
  if(chose[0] == 'e')
  {
   send(sockfd, "exit", 5, 0);
   close(sockfd);
   exit(0);
  }
  else
  {
   bzero(client_passwd, sizeof(client_passwd));
   bzero(passwd, sizeof(passwd));
   bzero(buf, sizeof(buf));
   printf("please input you name/n");
   scanf("%s", client_passwd);
   printf("please input you passwd/n");
   scanf("%s", passwd);
   strcat(client_passwd, passwd);
   
   /*send name and passwd*/
   send(sockfd, client_passwd, strlen(client_passwd), 0);
   recv(sockfd, buf, sizeof(buf), 0);
   
   if((strncmp(buf, "right", 5)) == 0)
   {
    printf("ok ! you pass the check/n");
    break;
   }
   else
    printf("name and passwd is error/n");
   
  }
 }  
}


int tra_file(int sockfd)
{
 char  buf[MAXDATASIZE];
 int ssize, rsize;
 int i = 0;
 FILE *fp;
 char t_file_name[100];
 while(1)
 { 
   printf("*********OK! you name and passwd is right*******/n");
   printf("please input you want to transmission file /n");
   scanf("%s", t_file_name);
   fprintf(stdout, "send file name is:%s/n", t_file_name);
   send(sockfd, t_file_name, 100, 0);
   if((fp = fopen(t_file_name, "rb")) == NULL)
   {
    perror("cannot open file");
    return 0;    
   }
  
   /*send file*/
   while(!feof(fp))
   {
   bzero(buf, sizeof(buf));
   rsize = fread(buf, 1, MAXDATASIZE, fp);
   ssize = (send(sockfd, buf, rsize, MSG_DONTROUTE));
   i++;
   printf("i =%d ,rsize =%d, ssize=%d/n", i, rsize, ssize);
   }
   fclose(fp);
   printf("ok! you send over/n"); 
   sleep(1);
   send(sockfd, "end", 4, 0);
   break;

 }
 return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值