给我写一段简单的epoll 和 signal 的服务器-客户端代码示例
时间: 2024-05-06 14:19:21 浏览: 8
好的,以下是一个简单的 epoll 和 signal 的服务器-客户端代码示例:
服务器端代码:
```C++
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#define MAX_EVENTS 10
#define BUF_SIZE 256
using namespace std;
int main(int argc, char ** argv)
{
if (argc != 2)
{
cout << "Usage: " << argv[0] << " <port>" << endl;
return 1;
}
int server_port = atoi(argv[1]);
int server_sockfd;
struct sockaddr_in server_addr;
// 创建 Socket
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 设置地址重用
int reuse = 1;
setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
// 设置地址和端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(server_port);
// 绑定 Socket
bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
// 监听 Socket
listen(server_sockfd, 10);
int epoll_fd, nfds;
struct epoll_event ev, events[MAX_EVENTS];
char buffer[BUF_SIZE];
// 创建 epoll
epoll_fd = epoll_create(10);
// 添加 server_sockfd 到 epoll 中
ev.events = EPOLLIN;
ev.data.fd = server_sockfd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_sockfd, &ev);
while (1)
{
// 等待事件发生
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds == -1)
{
perror("epoll_wait");
break;
}
// 处理事件
for (int i = 0; i < nfds; i++)
{
if (events[i].data.fd == server_sockfd)
{
// 接受客户端连接请求
int client_sockfd;
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &client_len);
// 添加 client_sockfd 到 epoll 中
ev.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
ev.data.fd = client_sockfd;
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_sockfd, &ev);
}
else if (events[i].events & EPOLLIN)
{
// 处理读事件
int sockfd = events[i].data.fd;
int n = read(sockfd, buffer, BUF_SIZE);
if (n == 0)
{
// 客户端关闭连接
close(sockfd);
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, sockfd, &ev);
}
else if (n > 0)
{
// 发送数据到客户端
write(sockfd, buffer, n);
}
else
{
perror("read");
}
}
else if (events[i].events & EPOLLRDHUP)
{
// 处理客户端关闭连接事件
int sockfd = events[i].data.fd;
close(sockfd);
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, sockfd, &ev);
}
else
{
// 处理其他事件
}
}
}
// 关闭 Socket
close(server_sockfd);
return 0;
}
```
客户端代码:
```C++
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#define BUF_SIZE 256
using namespace std;
int running = 1;
void sig_handle(int signo)
{
if (signo == SIGINT)
{
cout << "Terminating client..." << endl;
running = 0;
}
}
int main(int argc, char ** argv)
{
if (argc != 3)
{
cout << "Usage: " << argv[0] << " <server_ip> <server_port>" << endl;
return 1;
}
int server_port = atoi(argv[2]);
int client_sockfd;
struct sockaddr_in server_addr;
char buffer[BUF_SIZE];
// 创建 Socket
client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 设置地址和端口
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(server_port);
// 连接到服务器
connect(client_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
// 注册信号处理函数
signal(SIGINT, sig_handle);
// 循环读取用户输入并发送到服务器
while (running)
{
memset(buffer, 0, BUF_SIZE);
fgets(buffer, BUF_SIZE, stdin);
int n = write(client_sockfd, buffer, strlen(buffer));
if (n < 0)
{
perror("write");
break;
}
n = read(client_sockfd, buffer, BUF_SIZE);
if (n < 0)
{
perror("read");
break;
}
buffer[n] = '\0';
cout << "Server reply:" << buffer;
}
// 关闭 Socket
close(client_sockfd);
return 0;
}
```
希望这个代码示例能对您有所帮助。如果您有任何疑问,请随时问我。