linux Socket

title: linux Socket
categories: linux
toc: true
mathjax: true
tags: 
- Socket
- linux
widgets:
-
    type: toc
    position: left
-
    type: profile
    position: left
    author: Runope
    # Author title
    author_title: 不知不论,不做不论
    # Author's current location
    location: Nanjin,jiangsu
    # URL or path to the avatar image
    avatar: https://en.gravatar.com/userimage/194935117/7129e2095de79a9dd97e5cc344acaba2?size=200
    # Whether show the rounded avatar image
    avatar_rounded: false
    # Email address for the Gravatar
    gravatar: 275358499@qq.com
    # URL or path for the follow button
    follow_link: 'https://github.com/runope'
-
    type: recent_posts
    position: left

基本的UDP Socket编程

UDP通信的流程比较简单,因此要搭建这么一个常用的UDP通信框架也是比较简单的。以下是UDP的框架图。

UDP SOCKET通信

由以上框图可以看出,客户端要发起一次请求,仅仅需要两个步骤(socket和sendto),而服务器端也仅仅需要三个步骤即可接收到来自客户端的消息(socket、bind、recvfrom)。

Send, sendto, 和 sendmsg 用于向另一个套接字传递消息. Send 仅仅用于连接套接字,而 sendtosendmsg 可用于任何情况下.

  • read()/write()
  • recv()/send()
  • readv()/writev()
  • recvmsg()/sendmsg()
  • recvfrom()/sendto()

目标地址用 to 指定, tolen 定义其长度.消息的长度用 len 指定. 如果消息太长不能通过下层协议,函数将返回 EMSGSIZE 错误,消息也不会被送出.

在数据传送过程中所产生的错误不会返回给 send. 如果发生本地错误,则返回-1.

当要发送的消息长度大于套接字当前可用缓冲区时, send 将阻塞,除非在套接字上设置了非阻塞式输入输出模式. 对于非阻塞模式,这种情况下将返回 EAGAIN 错误.

udp的connect函数

UDP网络编程中也有connect函数,但它仅仅用于表示确定了另一方的地址,并没有其他含义。
有了以上认识后,我们可以知道UDP套接字有以下区分:
1)未连接的UDP套接字
2)已连接的UDP套接字

对于未连接的套接字,也就是我们常用的的UDP套接字,我们使用的是sendto/recvfrom进行信息的收发,目标主机的IP和端口是在调用sendto/recvfrom时确定的;

在一个未连接的UDP套接字上给两个数据报调用sendto函数内核将执行以下六个步骤:
1)连接套接字
2)输出第一个数据报
3)断开套接字连接
4)连接套接字
5)输出第二个数据报
6)断开套接字连接

对于已连接的UDP套接字,必须先经过connect来向目标服务器进行指定,然后调用read/write进行信息的收发,目标主机的IP和端口是在connect时确定的,也就是说,一旦connect成功,我们就只能对该主机进行收发信息了。

已连接的UDP套接字给两个数据报调用write函数内核将执行以下三个步骤:
1)连接套接字
2)输出第一个数据报
3)输出第二个数据报

由此可以知道,当应用进程知道给同一个目的地址的端口号发送多个数据报时,显示套接字效率更高。

下面给出带connect函数的UDP通信框架

使用connect函数的UDP通信框架

Socket端口通信运行在会话层,并不是应用层,Socket抓包的原理与应用层Http(s)有着显著的区别。准确的说,Http(s)抓包是真正的“中间人”抓包,而Socket抓包是在接口上进行转储;Http(s)抓包是明显的将一套C/S架构通信分裂成两套完整的通信过程,而Socket抓包是在接口上将发送与接收的内容存储下来,并不干扰其原本的通信过程。

对于安卓应用来说,Socket通信天生又分为两种JavaSocket通信和NativeSocket通信。

  • Java层:使用的是java.net.InetAddressjava.net.Socketjava.net.ServerSocket等类,与证书绑定的情形类似,也可能存在着自定义框架的Socket通信,这时候就需要具体情况具体分析,比如谷歌的protobuf框架等;
  • Native层:一般使用的是C Socket API,一般hooksend()recv()函数可以得到其发送和接受的内容

Java层

Socket通信

Native层

Socket通信

一般使用的是C Socket API,一般hooksend()recv()函数可以得到其发送和接受的内容。udp一般使用的sendto()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值