服务端头文件
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; }
|