diff --git a/client.cpp b/client.cpp new file mode 100644 index 0000000..a39cc30 --- /dev/null +++ b/client.cpp @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define SERVER_PORT 9876 +#define MESSAGE_LEN 1024 + +using namespace std; + +int main(int argc, char* argv[]){ + + int socket_fd; + int on = 1; + int ret = -1; + struct sockaddr_in serveraddr; + char send_buf[MESSAGE_LEN] = "Hello ! This is Client"; + char recv_buf[MESSAGE_LEN]; + + /* 1. 创建文件描述符 */ + socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if(socket_fd == -1){ + std::cout << "Failed to create socket !" << std::endl; + exit(-1); + } + // 设置 socket 选项 + ret = setsockopt(socket_fd, + SOL_SOCKET, + SO_REUSEADDR, + (void *)&on, + sizeof(on)); + if(ret == -1){ + std::cout << "Failed to set socket !" << std::endl; + exit(-1); + } + /* 2. 连接服务器 */ + // 配置服务端信息 + serveraddr.sin_family = AF_INET; + serveraddr.sin_port = htons(SERVER_PORT); + serveraddr.sin_addr.s_addr = inet_addr("10.250.16.149"); + bzero(&(serveraddr.sin_zero), 8); // 将预留位赋值为0 + // 连接 + ret = connect(socket_fd, + (struct sockaddr *)&serveraddr, + sizeof(struct sockaddr)); + if(ret == -1){ + std::cout << "Failed to connect !" << std::endl; + exit(-1); + } + + /* 3. 发送数据 */ + while(1){ + // 从控制台输入要发送的数据 + memset((void *)send_buf , 0, MESSAGE_LEN); + cin.getline(send_buf, 90); + // 发送数据 + ret = send(socket_fd, (void *)send_buf, strlen(send_buf), 0); + if(ret <= 0){ + std::cout << "Failed to send data !" << std::endl; + break; + } + std::cout << "Client Send --------> \n" << send_buf << std::endl; + + /* 4. 接收数据 */ + ret = recv(socket_fd, (void *)recv_buf, MESSAGE_LEN, 0); + if(ret <= 0){ + break; + } + // 要把接收到的数据的数组中此条长度的后面切掉,否则会出现拼接上一次数据的现象 + recv_buf[ret] = '\0'; + std::cout << "Recv From Server------------> \n" << recv_buf << std::endl; + bzero((void *)recv_buf, MESSAGE_LEN); + } + close(socket_fd); + return 0; +} + diff --git a/server.cpp b/server.cpp new file mode 100644 index 0000000..2f6fde9 --- /dev/null +++ b/server.cpp @@ -0,0 +1,136 @@ +/* + 使用 epoll 的服务端程序 +*/ +#include +#include +#include +#include +#include +#include +#include + +#define SERVER_PROT 9876 +#define MESSAGE_LEN 1024 +#define MAX_EVENTS 20 +#define TIMEOUT 500 + +int main(int argc, char* argv[]){ + int socket_fd, accept_fd; + int on = 1; + int ret = -1; + struct sockaddr_in localaddr, remoteaddr; + socklen_t addrlen; + char recv_buf[1024]; + int epoll_fd; + struct epoll_event ev, events[MAX_EVENTS]; + int event_number; + int flags; + + // 1. 创建套接字文件描述符,并设置 socket 选项 + socket_fd = socket(AF_INET, SOCK_STREAM, 0); + if(socket_fd == -1){ + std::cout << "Failed to create socket !" << std::endl; + exit(-1); + } + ret = setsockopt(socket_fd, + SOL_SOCKET, + SO_REUSEADDR, + &on, + sizeof(on)); + if(ret == -1){ + std::cout << "Failed to set socket !" << std::endl; + } + + /* 要把文件描述符设置为非阻塞的 */ + flags = fcntl(accept_fd, F_GETFL, 0); + fcntl(accept_fd, F_SETFL, flags | O_NONBLOCK); + + // 2. 绑定端口和地址 + localaddr.sin_family = AF_INET; + localaddr.sin_port = htons(SERVER_PROT); + localaddr.sin_addr.s_addr = INADDR_ANY; + bzero(&(localaddr.sin_zero), 8); // 填充 0 到数组中 + + ret = bind(socket_fd, + (struct sockaddr *)&localaddr, + sizeof(struct sockaddr_in)); + if(ret == -1){ + std::cout << "Failed to bind the socket !" << std::endl; + exit(-1); + } + + // 3. 开始监听 + ret = listen(socket_fd, 10); //由于 listen 一次只能接受一个,所以需要一个队列来存放并发的请求,长度为10够了 + if(ret == -1){ + std::cout << "Failed to listen... !" << std::endl; + exit(-1); + } + std::cout << "will to listen port: " << SERVER_PROT << std::endl; + /* epoll_1:创建一个 epoll 文件描述符 */ + epoll_fd = epoll_create(256); + ev.events = EPOLLIN; + ev.data.fd = socket_fd; + /* epoll_2:将监听文件描述符添加到 epoll_fd 中 */ + epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &ev); + + addrlen = sizeof(struct sockaddr_in); + for(;;){ + /* epoll_3:等待事件,相当于 select 函数 */ + event_number = epoll_wait(epoll_fd, events, MAX_EVENTS, TIMEOUT); + + for(int i=0; i 0){ + /* 打印数据 */ + recv_buf[ret] = '\0'; + std::cout << "Server Recv:-----> " << recv_buf << std::endl; + /* 数据回显 */ + ret = send(events[i].data.fd, + (void *)recv_buf, + MESSAGE_LEN, + 0); + } + } + } + } + close(socket_fd); + return 0; +} + diff --git a/tproxy_example.c b/tproxy_example.c index 508d60c..895c1b5 100644 --- a/tproxy_example.c +++ b/tproxy_example.c @@ -38,6 +38,7 @@ int handle_epollin(tproxy_conn_t *conn){ //I need to make a system call to determin which socket if(ioctl(conn->local_fd, FIONREAD, &numbytes) != -1 && numbytes > 0){ + fprintf(stderr, "received data.\n"); fd_in = conn->local_fd; fd_out = conn->remote_fd; } else { diff --git a/tproxy_example_conn.c b/tproxy_example_conn.c index c58c81e..1e9e168 100644 --- a/tproxy_example_conn.c +++ b/tproxy_example_conn.c @@ -10,7 +10,8 @@ #include #include #include - +#include +#include #include "tproxy_example_conn.h" //Createas a socket and initiates the connection to the host specified by