最近想写一个
网络库。想要实现的目标:
1. 负责收发消息,不关心消息格式
2. 动态添加监听端口
3. 动态添加对外连接
4. 关闭连接
网络层接收到消息,向外转发这个过程,不复杂。让使用者提供一个接收的函数。当网络层接收到一段写入,将其封装后直接写入这个接收函数。接下来的对消息的处理就不属于网络层的处理范围。
1. 负责收发消息,不关心消息格式
2. 动态添加监听端口
3. 动态添加对外连接
4. 关闭连接
网络层接收到消息,向外转发这个过程,不复杂。让使用者提供一个接收的函数。当网络层接收到一段写入,将其封装后直接写入这个接收函数。接下来的对消息的处理就不属于网络层的处理范围。
关键的是消息的写出(也就是向网络层写入)该如何处理?如果传统的把socket套接字开放给使用者,这样不但不符合封装性,而且造成混乱,届时可能滥用线程和锁,造成维护上的复杂性。(PS:我们现在的项目就是使用线程+锁,复杂,难懂)。这个问题困扰了我一个下午,直到晚上洗澡时,我突然想起当初在拜读云风的skynet时,看到他对pipe的灵活使用。我之前对pipe的认知,只是停留在在父子进程间的单向通信。但是程序员不该死板,书本看到的东西都可以被灵活使用。可以在外部与网络层之间使用pipe搭建一个桥。这样就可以把所有的写入都归入到同一个的接口上。使设计与逻辑变的简单,顺畅。
对外开放接口如下:"net_socket.h"
#include <netinet/in.h>
#define SOCKET_MSG_ACCEPT 1
#define SOCKET_MSG_CONNECT 2
#define SOCKET_MSG_DATA 3
#define SOCKET_MSG_CLOSE 4
struct socket_msg_accept {
int id;
struct sockaddr_in addr;
};
struct socket_msg_connect {
int id;
struct sockaddr_in addr;
};
struct socket_msg_close {
int id;
};
struct socket_msg_data {
int id;
int buf_len;
char *buf;
};
struct socket_server;
typedef struct socket_server socket_server;
typedef void (*msg_func)(int type, void*msg, int msg_len);
socket_server *socket_server_create(msg_func f);
void socket_server_poll(socket_server* ss);
void listen_socket(socket_server *ss, int port);
void connect_socket(socket_server *ss, char *ip, int ip_len, int port);
void write_socket(socket_server *ss, int id, char *msg, int msg_len);
void close_socket(socket_server *ss, int id);
此项目只是雏形,没经过详细测试,望大家多多指导,多提pr。接口部分的设计有借鉴云风的skynet