最近在读大神云风的开源服务器架构skynet,其中的网络库,云风已经单独开来,可以独立使用。
开源地址:
https://github.com/cloudwu/socket-server
网络库已经封装了socket的epoll.
在下载起来的世里面,已经包含了一个例子,但觉得不够明了。于是自己写了个测试例子,分为服务端了客户端,服务端启动并监听端口,客户端启动并连接服务器,向服务器发送消息,并得到服务器的反馈。
服务端代码:
#include "socket_server.h" #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> static void * _poll(void * ud) { struct socket_server *ss = ud; struct socket_message result; for (;;) { int type = socket_server_poll(ss, &result, NULL); // DO NOT use any ctrl command (socket_server_close , etc. ) in this thread. switch (type) { case SOCKET_EXIT: return NULL; case SOCKET_DATA: printf("message(%lu) [id=%d] size=%d %s\n",result.opaque,result.id, result.ud, result.data); // free(result.data); socket_server_send(ss, result.id, result.data, result.ud) ; break; case SOCKET_CLOSE: printf("close(%lu) [id=%d]\n",result.opaque,result.id); break; case SOCKET_OPEN: printf("open(%lu) [id=%d] %s\n",result.opaque,result.id,result.data); break; case SOCKET_ERROR: printf("error(%lu) [id=%d]\n",result.opaque,result.id); break; case SOCKET_ACCEPT: printf("accept(%lu) [id=%d %s] from [%d]\n",result.opaque, result.ud, result.data, result.id); socket_server_start(ss,201,result.ud); break; } } } static void test(struct socket_server *ss) { pthread_t pid; pthread_create(&pid, NULL, _poll, ss); // int c = socket_server_connect(ss,100,"127.0.0.1",80); // printf("connecting %d\n",c); int l = socket_server_listen(ss,200,"127.0.0.1",8888,32); printf("listening %d\n",l); socket_server_start(ss,201,l); // int b = socket_server_bind(ss,300,1); // printf("binding stdin %d\n",b); // int i; // for (i=0;i<100;i++) { // socket_server_connect(ss, 400+i, "127.0.0.1", 8888); // } // sleep(5); // socket_server_exit(ss); pthread_join(pid, NULL); } int main() { struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, 0); struct socket_server * ss = socket_server_create(); test(ss); // socket_server_release(ss); return 0; }
客户端代码:
#include "socket_server.h" #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> static void * _poll(void * ud) { struct socket_server *ss = ud; struct socket_message result; for (;;) { int type = socket_server_poll(ss, &result, NULL); // DO NOT use any ctrl command (socket_server_close , etc. ) in this thread. switch (type) { case SOCKET_EXIT: return NULL; case SOCKET_DATA: printf("message(%lu) [id=%d] size=%d %s\n",result.opaque,result.id, result.ud, result.data); free(result.data); break; case SOCKET_CLOSE: printf("close(%lu) [id=%d]\n",result.opaque,result.id); break; case SOCKET_OPEN: printf("open(%lu) [id=%d] %s\n",result.opaque,result.id,result.data); break; case SOCKET_ERROR: printf("error(%lu) [id=%d]\n",result.opaque,result.id); break; case SOCKET_ACCEPT: printf("accept(%lu) [id=%d %s] from [%d]\n",result.opaque, result.ud, result.data, result.id); break; } } } int main() { struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, 0); struct socket_server * ss = socket_server_create(); pthread_t pid; pthread_create(&pid, NULL, _poll, ss); int c = socket_server_connect(ss,100,"127.0.0.1",8888); printf("connecting %d\n",c); char buff[1024]; while(fgets(buff, sizeof(buff), stdin) != NULL) { buff[strlen(buff)-1] = '\n'; char* sendBuf = malloc(strlen(buff) + 1); memcpy(sendBuf, buff, strlen(buff)); socket_server_send(ss, c, sendBuf, strlen(sendBuf)); } pthread_join(pid, NULL); socket_server_release(ss); return 0; }