移植SimpleNet到Linux

最近我一直在学嵌入式Linux,总想在ARM板子上写点程序。所谓万事开头难,所以找了本Linux编程入门书(Advanced-linux-programming)看看:

为了练手我就把之前基于Window Socket的SimpleNet移植到Linux下,整个过程花了我两天时间。

其实Window Socket与Linux Socket几乎差不多,我参考了POCO库的net部分的跨平台移植,移植的几点如下:

  1. 加入Linux的头文件:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/ioctl.h>
    #include <netinet/in.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    
  2. 修改类型和函数:
    #define SOCKET int
    #define SOCKET_LEN_TYPE socklen_t
    #define INVALID_SOCKET (-1)
    #define SOCKET_ERROR   (-1)
    #define WSAGetLastError() errno
    #define WSAEWOULDBLOCK EWOULDBLOCK
    // linux下close socket用::close
    #define snet_closesocket(x) ::close(x)
    
  3. Linux下fd_set与Windows下完全不同,所以抛弃原来为Windows写的Fdset(无socket限制),直接用Linux默认操作(最多1024个socket)。
  4. Linux下select函数第一个参数必须为所有fd_set的socket的最大值加1,
  5. Linux下设置socket tcp keepalive和block。

大致如此,还有很多细节就不一一描述了,移植果然很痛苦啊:)。

接下来就是写Makefile了,因为之前有过经验,不是很难。不过比较头疼的是gnu make不能自动推导头文件依赖,必须间接生成再导入(我之前用的borland make有自动推导头文件功能,很爽),最后写好的Makefile感觉就有点臃肿了。

CFLAGS=-Wall -O2
CC=g++
SRC=Src
OBJECTS=$(SRC)/snet_log.o $(SRC)/snet_session.o $(SRC)/snet_sessionManager.o $(SRC)/snet_tool.o
TARGET=libsimple_net.a

# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d)

$(TARGET):$(OBJECTS)
        ar cr $(TARGET) $(OBJECTS)

# compile and generate dependency info;
# more complicated dependency computation, so all prereqs listed
# will also become command-less, prereq-less targets
#   sed:    strip the target (everything before colon)
#   sed:    remove any continuation backslashes
#   fmt -1: list words one per line
#   sed:    strip leading spaces
#   sed:    add trailing colons
$(OBJECTS):%.o:%.cpp
        $(CC) $(CFLAGS) -I./Src -c
 
lt; -o $@ $(CC) -MM $(CFLAGS) $*.cpp > $*.d @cp -f $*.d $*.d.tmp @sed -e 's/.*://' -e 's/\$//' < $*.d.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$/:/' >> $*.d @rm -f $*.d.tmp clean: -rm -f $(OBJECTS) $(OBJS:.o=.d) $(TARGET) 

编译链接后生成SimpleNet lib库libsimple_net.a,用Test目录下的聊天室测试程序链接运行:

目前SimpleNet功能上偏弱,只支持同步Poll轮询方式,下一步打算支持线程异步方式。按惯例,所有的程序源码在我的github上