python程序間傳遞檔案描述符擴充套件庫

2021-12-30 00:06:43 字數 3577 閱讀 8297

由於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...