Socket编程

socket编程进行的是端到端的通信,设置参数也只能是端到端协议之上网络层和传输层的。在网络层,需要指定是IPV4还是IPV6,指定是TCP还是UDP

基于TCP协议的Socket程序函数调用过程。

  • TCP要先监听一个端口,一般是先调用bind函数,给这个socket赋予一个IP和端口。
  • 然后调用listen函数进行监听。在TCP的状态图里面有一个这个状态,当调用了这个函数之后,服务端就进入了这个状态,这时候客户端就可以发起连接了
  • 在内核中为每个socket维护两个队列。一个是已经建立连接的队列,这时候三次握手已经完毕,处于established状态;一个是还没有完全建立连接的队列,这时候还没有完成三次握手,处于syn_rcvd状态。
  • 服务端调用accept函数,拿出一个已经完成的链接处理
  • 在服务端等待时,客户端可以connect函数发起连接。先在参数中指明要连接的IP和PORT,然后发起三次握手。内核会给客户端分配一个临时端口,一旦握手成功,服务端的accept就会返回另一个socket。
    监听的socket和真正用来传数据的socket是两个,一个作为监听socket,一个叫做已连接socket。建立连接之后,双方通过read和write 函数来读写数据, 就像在一个文件流里面写东西。
    在这里插入图片描述

基于UDP协议的socket函数调用过程

UDP是没有连接的,不需要listen和connect,但是它仍然需要bind函数。UDP是没有维护连接状态的,因而不需要每对连接建立一组socket,而是只要有一个socket 就能够和多个客户端通信,每次通信的时候,都调用sendto 和recvfrom,都可以传入IP地址和端口。
在这里插入图片描述如何让服务端为更多的客户端服务:

  • 多进程方式
    会将资源都复制一份。

  • 多线程方式
    在 Linux 下,通过 pthread_create 创建一个线程,也是调用 do_fork。不同的是,虽然新的线程在task 列表会新创建一项,但是很多资源,例如文件描述符列表、进程空间,还是共享的,只不过多了个引用而已。

  • IO复用

    • select
      由于 Socket 是文件描述符,因而某个线程盯的所有的 Socket,都放在一个文件描述符集合 fd_set 中,这就是项目进度墙,然后调用 select 函数来监听文件描述符集合是否有变化。一旦有变化,就会依次查看每个文件描述符。那些发生变化的文件描述符在 fd_set 对应的位都设为 1,表示 Socket 可读或者可写,从而可以进行读写操作,然后再调用 select,接着盯着下一轮的变化。
      问题: 每次文件描述符中有socket发生变化的时候,都需要用轮询的方式查看进度;监视的项目数量又FD_SETSIZE限制。
    • epoll
      它在内核中的实现不是通过轮询的方式,而是通过注册 callback 函数的方式,当某个文件描述符发送变化的时候,就会主动通知。能完成这件事情的函数叫 epoll,它在内核中的实现不是通过轮询的方式,而是通过注册 callback 函数的方式,当某个文件描述符发送变化的时候,就会主动通知。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值