面试时经常会问到网络库,好久没看过这块知识了,实现一下,用到了一下一些知识点
- socket搭建网络库必须用到的
- epoll 多路复用技术用的是epoll
- pthread 服务器用到了多线程,主线程启动服务器,子线程处理来自各个连接的数据
- pipe 用在进程间通讯 0是读 1是写
- sem 信号 用在进程间通讯
- pthread_con_t 条件变量,用于进程间通讯
- cmake 用来编译工程
下面是服务器代码:epollserver.cpp
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/epoll.h>
#include<errno.h>
#include<pthread.h>
#include <semaphore.h>
using namespace std;
typedef struct sockaddr_in sockaddr_in;
sem_t sem; // 信号
pthread_cond_t cond; // 条件变量
pthread_mutex_t mutex; // 互斥锁
int pipeHandle[2]; // 管道 0读端, 1写端
void set_non_blocking(int sock)
{
int flag;
flag = fcntl(sock, F_GETFL);
if (flag < 0) {
cout << "error fcntl(sock, GETFL)! " << endl;
return;
}
flag |= O_NONBLOCK;
if (fcntl(sock, F_SETFL, flag) < 0) {
cout << "error fcntl(sock, F_SETFL, opts)! " << endl;
return;
}
}
void* voteAction(void* data) {
while (1)
{
pthread_cond_wait(&cond, &mutex); // 无条件等待,与互斥锁配合防止多个线程同时调用
pthread_t senderId;
read(pipeHandle[0], &senderId, sizeof(senderId));
cout << "vote action: people " << senderId << " vote action happen, please call 110" << endl;
write(pipeHandle[1], &senderId, sizeof(senderId));
sem_post(&sem);
}
return NULL;
}
void* policeCenter(void* data)
{
while (1) {
sem_wait(&sem);
pthread_t senderId;
read(pipeHandle[0], &senderId, sizeof(senderId));
cout << "110 center recevice people" << senderId << " notify vote event happened" << endl;
}
return NULL;
}
struct my_params {
int