本程式說明:
通過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;
}