服务端头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#ifndef SERVER_H
#define SERVER_H

#include "my_header.h"
#include <arpa/inet.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/mman.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <shadow.h>
#include <crypt.h>
#include <syslog.h>
#define PATHLEN 32
#define DEPTH 30
#define ROOT "/home/hespethor"
#define BEGIN "."
#define LENGTH 1024
//枚举信号
enum Command{
CD,
LS,
PWD,
PUTS,
GETS,
REMOVE,
MKDIR,
RMDIR
};
//信号的发送接收,跟客户端对应
typedef struct SignalSend_s{
int sig_t; //用数字代替信号
int size; //路径个数
char pathname[DEPTH][PATHLEN]; //接收路径
char path[LENGTH];
}SignalSend_t;
//收发信息的结构体
typedef struct FileBuf_s{
int size; //信息长度
char buf[LENGTH * 2]; //接收信息
}FileBuf_t;

typedef struct Node_s{
int netfd;
int depth; //下标
char path[DEPTH][PATHLEN];
struct Node_s *next;
}Node_t;

typedef struct Queue_s{
Node_t *head; //头
Node_t *tail; //尾
int count; //客户数量
}Queue_t;
//线程共享资源
typedef struct Resource_s{
int pidnum;
int freepid;
SignalSend_t *sig; //指向结构体signal
Queue_t *queue;
pthread_mutex_t mutex; //锁
pthread_cond_t cond; //信号,接文件的
}Resource_t;

void *Worker(void *arg);
int SockfdCreate(char *ip, char *port);
int EpollCreate(int sockfd);
void InitQueue(Queue_t *queue);
void EnQueue(Queue_t *queue, int netfd);
void DeQueue(Queue_t *queue);
int RecvCommand(Node_t *p);
int RecvFile(int sockfd);
int TransFile(int sockfd, char *pathname);
int JudgePath(const SignalSend_t *cmd, int *depth, char cpath[DEPTH][PATHLEN],char *path);
int CmdCd(char *path, const int depth, FileBuf_t *msg, Node_t *p);
int CmdLs(const char* path, FileBuf_t *msg);
int IsLoading(int netfd);
#endif

服务端主体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "Server.h"

int main(int argc, char* argv[]) {
ARGS_CHECK(argc, 4); // 检查参数:./Server ip port thread_num

Resource_t *res = (Resource_t *)malloc(sizeof(Resource_t));
ERROR_CHECK(res, NULL, "malloc Resource");
res->pidnum = atoi(argv[3]);
res->freepid = res->pidnum; //空闲线程个数
res->queue = (Queue_t *)malloc(sizeof(Queue_t));
ERROR_CHECK(res->queue, NULL, "malloc Queue");
InitQueue(res->queue); //初始化信息队列

int sockfd = SockfdCreate(argv[1], argv[2]);

pthread_mutex_init(&res->mutex, NULL);
pthread_cond_init(&res->cond, NULL);

pthread_t pid[res->pidnum];
for (int i = 0; i < res->pidnum; i++) {
int ret = pthread_create(&pid[i], NULL, Worker, res);
ERROR_CHECK(ret, -1, "pthread_create");
printf("Pid == %ld created\n", pid[i]);
}

while(1){
pthread_mutex_lock(&res->mutex);
while(res->queue->count > res->freepid){
pthread_cond_wait(&res->cond, &res->mutex);
}
pthread_mutex_unlock(&res->mutex);
int netfd = accept(sockfd, NULL, NULL);
//此处加入密码验证,缺失就关闭;
if(IsLoading(netfd) != 0){
close(netfd);
continue;
}
pthread_mutex_lock(&res->mutex);
EnQueue(res->queue, netfd);
printf("count == %d\n", res->queue->count);
pthread_cond_broadcast(&res->cond);
pthread_mutex_unlock(&res->mutex);
}

for(int i = 0; i < res->pidnum; i++){
pthread_join(pid[i], NULL);
}
pthread_mutex_destroy(&res->mutex);
pthread_cond_destroy(&res->cond);
Node_t *p = res->queue->head;
while(p != NULL){
res->queue->head = res->queue->head->next;
free(p);
p = res->queue->head;
}
free(res->queue);
free(res);
return 0;
}

需要实现基于Linux系统的登录验证,执行时sudo ./Server 127.0.0.1 1234 5

初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "Server.h"

int SockfdCreate(char* ip, char* port){
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
ERROR_CHECK(sockfd, -1, "socket");

int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(port));
serveraddr.sin_addr.s_addr = inet_addr(ip);
int bret = bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
ERROR_CHECK(bret, -1, "bind");

listen(sockfd, 50);
printf("Server listening on %s:%s (sockfd=%d)\n", ip, port, sockfd);
return sockfd;
}

int EpollCreate(int sockfd){
int epfd = epoll_create(1);
ERROR_CHECK(epfd, -1, "epoll_create");

struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = sockfd;
int ctl_ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);
ERROR_CHECK(ctl_ret, -1, "epoll_ctl add sockfd");

return epfd;
}