由於python本身的執行緒基本上比較殘廢,所以為了利用機器的cpu,就不得不用上多程序。。。
在遊戲伺服器的設計中,最為常見的方式是:
掛乙個前端伺服器,專門來維護與客戶端的連線,然後將客戶端的請求資料**給後端伺服器。。。
上面的方式是現在最為正統的。。。
但是自己因為環境的限制,需要做到對客戶端透明,然後將後端的伺服器轉換成為多程序的。。。所以這裡就只有用一點比較彆扭的方法了,首先處理登入等一些常規的邏輯放在前端伺服器,當進入放進進行匹配戰鬥之後,將客戶端的socket連線直接交給後端伺服器,然後進行處理。。。。。
因此這裡就需要實現乙個python能用的檔案描述符傳遞擴充套件庫。。。。
還好自己用c語言做過類似的東西。。。所以基本上把**拿過來,再用cython做一層包裝,也就能用了,這裡就直接貼**吧:
#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);
上面是標頭檔案的定義,接下來把c語言的**貼上來:#include sr.h
int sr_connect(const char *name)
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)
strcpy(un.sun_path, name);
size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
if (connect(fd, (struct sockaddr *)&un, size) < 0)
// if (listen(fd, 10) < 0)
// 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)
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 0;
}
int recv_fd(int sock, char* data)
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)
int fd = *(int *)cmsg_data(cmptr);
strcpy(data, iov[0].iov_base);
free(cmptr);
return fd;
}void close_fd(int fd)
// int main()
// 最後貼上cython的包裝檔案:
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.sock
cdef int fd = sr_connect(dist)
send_fd(fd, fd, fdsaf);
def fjs_recv_fd(sock):
cdef int fd = sock
cdef char* data = malloc(33)
fd = recv_fd(fd, data)
try:
out_data = data
return (fd, out_data)
finally:
free(data)
def fjs_send_fd(fd1, fd2, data):
cdef int source = fd1
cdef int des = fd2
send_fd(source, des, data)
def fjs_close_fd(fd):
cdef int now_fd = fd
close_fd(fd)
嗯。。就上面這些**。。。這裡需要基於unix域socket。。。。
Linux 程序間傳遞檔案描述符
程序間傳遞開啟的檔案描述符,並不是傳遞檔案描述符的值。先說一下檔案描述符。對核心來說,所有開啟的檔案都會通過檔案描述符引用,檔案描述符在程序中是乙個非負整數,檔案描述符在程序中是從0開始,預設0與標準輸入關聯 1與標準輸出關聯 2與標準出錯關聯。之後程序每開啟乙個檔案或者建立乙個新檔案的時候,核心都...
Linux 程序間傳遞檔案描述符
程序間傳遞開啟的檔案描述符,並不是傳遞檔案描述符的值。先說一下檔案描述符。對核心來說,所有開啟的檔案都會通過檔案描述符引用,檔案描述符在程序中是乙個非負整數,檔案描述符在程序中是從0開始,預設0與標準輸入關聯 1與標準輸出關聯 2與標準出錯關聯。之後程序每開啟乙個檔案或者建立乙個新檔案的時候,核心都...
android程序間傳遞檔案描述符原理
在linux中,程序開啟乙個檔案,返回乙個整數的檔案描述符,然後就可以在這個檔案描述符上對該檔案進行操作。那麼檔案描述符和檔案到底是什麼關係?程序使用的是虛擬位址,不同程序間是位址隔離的,如何在兩個程序中傳遞檔案描述符,然後指向同一檔案 binder傳遞檔案描述符 核心中每個程序都使用task st...