Python inter-process transfer file descriptor extension Library
Since the threads in python are basically disabled, you have to use multi-process to take advantage of the machine's cpu...
The most common method in game server design is:
A front-end server is mounted to maintain the connection with the client, and then the client request data is forwarded to the backend server...
The above method is now the most orthodox...
However, due to environment restrictions, you must be transparent to the client and then convert the backend server into a multi-process... So here we only need to use a bit of awkward method. First, we need to handle some conventional logic such as logon on the front-end server. after entering the server for matching, send the socket connection of the client directly to the backend server for processing .....
So here we need to implement a file descriptor that can be used by python to pass the extension library ....
Fortunately, I have done similar things in C language... So basically we can get the code and use cython for a layer of packaging. Here we can directly paste the Code:
#include
#include
#include
#include
#include
#include
#include
int serv_listen(const char *name);int send_fd(int sock, int fd, char* data);int recv_fd(int sock, char *data); void close_fd(int fd);
The above is the definition of the header file, and then paste the C language code:
#include sr.hint sr_connect(const char *name){int fd, size;struct sockaddr_un un;memset(&un, 0, sizeof(un));un.sun_family = AF_UNIX;if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {printf(no1);return 0;}sprintf(un.sun_path, %s%05d, tmp, getpid());size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);if (bind(fd, (struct sockaddr *)&un, size) < 0) {printf(no2);return 0;}strcpy(un.sun_path, name);size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);if (connect(fd, (struct sockaddr *)&un, size) < 0) {printf(no3);return 0;}// if (listen(fd, 10) < 0) {// printf(no3);// }// char* hello = hello fjs;// ssize_t out = send(fd, (void*)hello, strlen(hello), 0);// send_fd(lis, lis);return fd;}int send_fd(int sock, int fd, char* data) { printf(here1: %s, data); struct iovec iov[1]; iov[0].iov_base = data; iov[0].iov_len = strlen(data); printf(len: %d, strlen(data)); printf(here2: %s, iov[0].iov_base); int cmsgsize = CMSG_LEN(sizeof(int)); struct cmsghdr* cmptr = (struct cmsghdr*)malloc(cmsgsize); if(cmptr == NULL){ return -1; } cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; // we are sending fd. cmptr->cmsg_len = cmsgsize; struct msghdr msg; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = cmptr; msg.msg_controllen = cmsgsize; *(int *)CMSG_DATA(cmptr) = fd; int ret = sendmsg(sock, &msg, 0); free(cmptr); if (ret == -1){ return -1; } return 0; } int recv_fd(int sock, char* data) { int cmsgsize = CMSG_LEN(sizeof(int)); struct cmsghdr* cmptr = (struct cmsghdr*)malloc(cmsgsize); if (cmptr == NULL) { return -1; } char buf[33]; // the max buf in msg. memset(buf, 0, 33); struct iovec iov[1]; iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf); struct msghdr msg; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = cmptr; msg.msg_controllen = cmsgsize; int ret = recvmsg(sock, &msg, 0); if (ret == -1) { return -1; } int fd = *(int *)CMSG_DATA(cmptr); strcpy(data, iov[0].iov_base); free(cmptr); return fd; }void close_fd(int fd){ close(fd);}// int main()// {// int lis = serv_listen(/tmp/fjs.sock);// printf(ok);// char* hello = hello fjs;// // ssize_t out = send(lis, (void*)hello, strlen(hello), 0);// send_fd(lis, lis);// }
Finally, paste the cython package file:
cdef extern from sr.h:extern int sr_connect(const char *name)extern int send_fd(int sock, int fd, char* data)extern int recv_fd(int sock, char* data)void close_fd(int fd)cdef extern from stdlib.h:extern void *malloc(unsigned int num_bytes)extern void free(void *ptr)def connect_and_send():cdef char* dist = /tmp/fjs.sockcdef int fd = sr_connect(dist)send_fd(fd, fd, fdsaf);def fjs_recv_fd(sock):cdef int fd = sockcdef char* data =
malloc(33)fd = recv_fd(fd, data)try:out_data = datareturn (fd, out_data)finally:free(data)def fjs_send_fd(fd1, fd2, data):cdef int source = fd1cdef int des = fd2send_fd(source, des, data)def fjs_close_fd(fd):cdef int now_fd = fdclose_fd(fd)
Well .. The above code... Here we need to base on the unix domain socket ....