传统网络通信
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
服务端:
肯定要有一个socket然后绑定fd和ip,port,当然这时候需要转换成网络字节序,然后一堆操作,绑定完成以后就用这个fd去监听这个端口,开启listen,然后等待连接就是调用accept阻塞在这里等待连接,客户端连接后循环阻塞读写。
客户端:
先要填充好socket,然后调用connect连接服务端,也要带上ip和端口号,建立连接以后,用write和read读写,最后关闭套接字。
可以看到这种网络模型有很多问题要解决:
阻塞I/O:也就是说服务端或者客户端的读写都会阻塞,这样毫无疑问程序太死板。
多路复用:服务端要解决I/O多路复用,也就是可以处理多个客户端,比如epoll,select,poll等多路复用技术。
信号事件驱动I/O:也就是说当有I/O时采取通知机制,而不是轮询。
异步I/O:异步进行I/O操作,因为读写都会耗时,这不利于高并发的服务器开发,可以采取多线程。
而且在传统这种网络编程中,socket细节还比较复杂,并且需要自行解决分包组包,粘包,异常重连,消息缓存,消息加密,且TCP是一对一连接,就是一个socket只能有有一个连接。
那么接下来就介绍一个zmq的基本使用,它帮我们解决了这些问题。
zmq是什么
zmq:我的理解就是,它是一个库,一个封装了网络通信过程,程序员只用使用它的接口就能进行网络编程,并且不在像之前那么麻烦,虽然现在可能还不够优秀,但是它的很多思想都是很好的,而且也有很多应用,所以尝试用它是一个好的选择。
客户端:
- 使用void *zmq_ctx_new ();,这个函数返回一个新的contex对象
- 使用**void *zmq_socket (void *context, int type);**得到一个socket对象,就是类似句柄,这个type是socket类型,抽象类12种,每一种对应一个场景。
- 使用**int zmq_connect (void *socket, const char *endpoint);**进行连接,连接也是非常简单的,传入一个字符串和scoket对象就可以了。
- 然后就可以使用接受发送函数进行传输了。
服务端:
- 使用void *zmq_ctx_new ();,这个函数返回一个新的contex对象
- 使用**void *zmq_socket (void *context, int type);**得到一个socket对象,就是类似句柄,这个type是socket类型,抽象类12种,每一种对应一个场景。
- 前两步是一样的,第三步绑定:**int zmq_bind (void *socket, const char *endpoint);**绑定ip和端口号。
- 然后就可以了。
总结一下,zmq的socket是可以复用的,可以同时连接多个客户端,连接只关注ip和端口号,然后服务端也是只用绑定ip和端口号,总之:真香。然后具体流程看代码:
客户端:
服务端: