//header.h
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <dirent.h>
#define BUFFERSIZE 1024
typedef struct sockaddr SA;
//服务器端
#include "header.h"
void ProcessList(int connfd);
void ProcessGet(int connfd, char buf[]);
void ProcessPut(int connfd, char buf[]);
void ProcessList(int connfd)
{
char buf[BUFFERSIZE];
DIR *mydir;
struct dirent *myitem;
mydir = opendir(".");
while ((myitem = readdir(mydir)) != NULL)
{
if ((strcmp(myitem->d_name, ".") == 0)
|| (strcmp(myitem->d_name, "..") == 0))
continue;
strcpy(buf, myitem->d_name);
send(connfd, buf, BUFFERSIZE, 0);
}
closedir(mydir);
return;
}
void ProcessGet(int connfd, char buf[])
{
int fd, nbyte;
if ((fd = open(buf+1, O_RDONLY)) < 0)
{
fprintf(stderr, "fail to open %s : %s\n", buf+1, strerror(errno));
buf[0] = 'N';
send(connfd, buf, BUFFERSIZE, 0);
return;
}
buf[0] = 'Y';
send(connfd, buf, BUFFERSIZE, 0);
while ((nbyte = read(fd, buf, BUFFERSIZE)) > 0)
{
send(connfd, buf, nbyte, 0);
}
close(fd);
return;
}
void ProcessPut(int connfd, char buf[])
{
int fd, nbyte;
if ((fd = open(buf+1, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
printf("fail to create %s on server\n", buf+1);
return;
}
while ((nbyte = recv(connfd, buf, BUFFERSIZE, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
return;
}
int main(int argc, char *argv[])
{
int listenfd, connfd;
char buf[BUFFERSIZE];
struct sockaddr_in server_addr;
if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-1);
}
#ifdef _DEBUG_
printf("socket is %d\n", listenfd);
#endif
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listenfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
perror("fail to bind");
exit(-1);
}
listen(listenfd, 5);
while ( 1 )
{
if ((connfd = accept(listenfd, NULL, NULL)) < 0)//等待客户端连接
{
perror("fail to accept");
break;
}
recv(connfd, buf, BUFFERSIZE, 0); //第一步收到客户端的业务请求
switch (buf[0])
{
case 'L' :
ProcessList(connfd);
break;
case 'G' :
ProcessGet(connfd, buf);
break;
case 'P' :
ProcessPut(connfd, buf);
break;
}
close(connfd);
}
return 0;
}
//客户端
#include "header.h"
void PrintHelp();
void ProcessList(struct sockaddr_in server_addr);
void ProcessGet(struct sockaddr_in server_addr, char command[]);
void ProcessPut(struct sockaddr_in server_addr, char command[]);
void PrintHelp()
{
printf("help : display help info\n");
printf("list : get file list of server\n");
printf("get : get <file>\n");
printf("put : put <file>\n");
printf("quit : quit the client\n");
return;
}
void ProcessList(struct sockaddr_in server_addr)
{
int sockfd, nbyte;
char buf[BUFFERSIZE]; //设置成局部变量可以互不影响
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to list\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_1;
}
strcpy(buf, "L"); //第一步要告诉服务器客户端需要干嘛
send(sockfd, buf, BUFFERSIZE, 0);
while ((nbyte = recv(sockfd, buf, BUFFERSIZE, 0)) != 0) //0放送方式 通常为0
{
printf("%s\n", buf);
}
ERROR_1:
close(sockfd);
return;
}
void ProcessGet(struct sockaddr_in server_addr, char command[])
{
int sockfd, nbyte, fd;
char buf[BUFFERSIZE];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_2;
}
sprintf(buf, "G%s", command+4);
send(sockfd, buf, BUFFERSIZE, 0);
recv(sockfd, buf, BUFFERSIZE, 0);
if (buf[0] == 'N') // no such file
{
printf("No such file on server\n");
goto ERROR_2;
}
if ((fd = open(command+4, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
printf("fail to create local file %s\n", command+4);
goto ERROR_2;
}
while ((nbyte = recv(sockfd, buf, BUFFERSIZE, 0)) > 0)
{
write(fd, buf, nbyte);
}
close(fd);
ERROR_2:
close(sockfd);
return;
}
void ProcessPut(struct sockaddr_in server_addr, char command[])
{
int sockfd, fd, nbyte;
char buf[BUFFERSIZE];
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
printf("fail to get\n");
return;
}
if (connect(sockfd, (SA *)&server_addr, sizeof(server_addr)) < 0)
{
printf("fail to connect server\n");
goto ERROR_3;
}
if ((fd = open(command+4, O_RDONLY)) < 0)
{
printf("fail to open %s\n", command+4);
goto ERROR_3;
}
sprintf(buf, "P%s", command+4);
send(sockfd, buf, BUFFERSIZE, 0);
while ((nbyte = read(fd, buf, BUFFERSIZE)) > 0)
{
send(sockfd, buf, nbyte, 0);
}
close(fd);
ERROR_3:
close(sockfd);
return;
}
int main(int argc, char *argv[])
{
int sockfd, fd, nbyte;
char command[32];
struct sockaddr_in server_addr;
if (argc < 3)
{
printf("Usage : %s <server_ip> : <port>\n", argv[0]);
exit(-1);
}
// XXX:step 1 int socket(int domain, int type, int protocol);
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "fail to socket : %s\n", strerror(errno));
exit(-1);
}
#ifdef _DEBUG_
printf("socket is %d\n", sockfd);
#endif
// XXX:step 2 int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
//server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
while ( 1 )
{
printf("<client> ");
fgets(command, 32, stdin);
command[strlen(command)-1] = '\0'; // overwrite the '\n'需要减一
if (strcmp(command, "help") == 0)
{
PrintHelp();
}
else if (strcmp(command, "list") == 0)
{
ProcessList(server_addr);
}
else if (strncmp(command, "get ", 4) == 0)
{
ProcessGet(server_addr, command);
}
else if (strncmp(command, "put ", 4) == 0)
{
ProcessPut(server_addr, command);
}
else if (strcmp(command, "quit") == 0)
{
printf("Bye\n");
break;
}
else
{
printf("wrong command, 'help' for command list\n");
}
}
return 0;
}