linux启动socket进程,在linux上开启一个socket服务(一)

之前写过一个socket的服务程序,只使用了accept进行处理,缺点是程序是阻塞的。

总结当时的思路是:

用listen监听请求,循环accept得到客户端句柄。为了实现多客户端共享该服务,我开辟了一个用于保存客户端句柄的数组,并为每个请求建立一个线程去处理。值得注意的是需要考虑多线程的同步与互斥。主线程A用于填充数组,由主线程开启的线程B负责循环读取数组,当数组有元素时会为客户端句柄创建处理线程C(x),它们之间的同步互斥关系可参加上篇文章。

这样做的好处是服务可以并发处理多个请求了,但是程序仍然是阻塞的,为了避免阻塞我不得不另外开启了线程B和C。但是linux中select函数,完全能让我的主线程避开完全阻塞,即使一段时间没有请求,主线程也能避开等待,而处理其它事情。这是非常重要的,线程的空等一定带来资源的浪费,最大化地让利用资源才能更好地提高程序执行效率。

因此,我又重新设计我的程序,思路如下:

(1)服务分两块,一块是处理client请求,另一块是处理非client请求(如外界的RPC请求),这里只说明client请求;

(2)暂时不考虑多client请求的情况,先跑通一个client再说。

(3)服务有三个重要的全局变量:一个fd_set, 一个存放句柄相关信息的watch table, 一个pending list。

主线程会开启一个loop线程,去感知fd_set,若有可读写的fd存在,则从watch_table中查出该fd相关的详细信息,最后放入到pending list中等待处理。

主线程或其它线程会组合请求句柄相关信息到watch table中,并将fd加入fd_set。

(4)这样

当客户端调用connect时,服务端的server_socket_fd是可读的,会触发一个处理函数,在处理函数中自然会得到客户端句柄client_fd,然后又可以封装该fd相关的信息,放入到watch table和fd_set中。

当客户端调用send时,服务端的client_fd是可读的,触发一个处理函数,这样就能得到客户端发来的请求信息了。

设计仍然存在许多改进提升之处:

(1)客户端与服务端没有协议的设计;

(2)不支持多客户端

(3)服务只能处理socket类型的请求。服务也有可能作为客户端请求其它服务,这时服务得到的响应也应该会有处理。

对此,我先考虑了不足(1)的设计,如下:

数据准备采用这种形式(ID, size, data)

ID表示请求标识;

size标识请求数据的长度,如几个int, 几个char等;

data是具体网络字节数据。

解析时,先解出ID,然后在列表中查找出该ID带有分发函数dispatchXXX,这里讲分发函数分成以下几种:

dispatchInt()  ----  代表处理的请求data是int类型的

dispathChar()  ----  代表处理的请求data是char类型的

dispathString()  ----  代表处理的请求data是string类型的

dispathVoid()  ----  代表处理的请求data是NULL的

……

在dispatchXXX中,解析出size和data,根据具体类型还原出具体的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值