linux socket网络编程详解


一、系统调用和应用编程接口

在讨论网络通信之前,
首先明确两个概念: 系统调用(system call)  和  应用编程接口(Application Programming Interface,API)

操作系统使用 系统调用 机制来实现 在应用程序 与 操作系统 之间进行控制权传递

当某个应用进程启动了系统调用时,控制权就从应用程序传递给操作系统。操作系统执行某个内部过程之后,把控制权返回给应用程序。
对程序员来说,每一个系统调用和一般程序设计中的函数调用非常相似,只是系统调用是将控制权传递给了操作系统。

图1、多个应用进程使用系统调用机制

当某个应用进程启动系统调用时,控制权就从应用进程传递给了系统调用接口
此接口再将控制权传递给计算机的操作系统。操作系统将此调用转给某个内部过程,并执行所请求的操作。
内部过程一旦执行完毕,控制权就又通过系统调用接口返回给应用进程。
系统调用接口实际上就是应用进程的控制权和操作系统的控制权进行转换的一个接口,即应用编程接口 API

从程序设计的角度看,API可以看做是操作系统 与 应用程序 之间的接口

现在的操作系统中已经驻留了TCP/IP协议栈。
可供应用程序使用TCP/IP的系统调用接口有如下几种:
  • Berkeley UNIX 操作系统定义了一种 API,它又称为套接字接口(socket interface)。 
  • 微软公司在其操作系统中采用了套接字接口 API,形成了一个稍有不同的 API,并称之为 Windows Socket。 
  • AT&T 为其 UNIX 系统 V 定义了一种 API,简写为 TLI (Transport Layer Interface)。  

在讨论网络编程的时候,常常把套接字作为 应用进程  传输层协议 之间的接口
套接字也已经成为操作系统内核的一部分。

应用进程通过套接字接入到网络

图2、应用进程通过套接字接入到网络

注意:套接字之上的进程是受应用程序控制的,而在套接字以下的传输层协议是由操作系统控制的。因此,只要应用程序使用TCP/IP协议进行通信,就必须通过套接字来与操作系统进行交互

套接字的作用
当应用进程需要使用网络进行通信时就发出socket系统调用,请求操作系统为其创建“套接字,以便把网络通信所需要的系统资源分配给该应用进程
操作系统为这些资源的总和用一个叫做套接字描述符的号码来表示,并把此号码返回给应用进程。应用进程所进行的网络操作都必须使用这个号码。
通信完毕后,应用进程通过一个关闭套接字的系统调用通知操作系统回收与该“号码”相关的所有资源。

下图展示了当应用进程发出socket系统调用时,操作系统所创建的套接字描述符与套接字数据结构的关系。


图3、调用socket套接字

二、网络编程几种常用的系统调用


1、建立连接阶段

当套接字创建后,它的端口号和IP地址都是空的,因此应用程序要调用bind来指明套接字的本地地址(本地端口号和本地IP地址)。
在服务器调用bind时,就是把本地端口号和本地IP地址填写在已经创建的套接字中。
客户端可以不调用bind,这时由操作系统内核自动分配一个动态端口号,通信结束后由系统收回。

服务器在调研bind后,还必须调研listen把套接字设置为被动方式,以便随时接受客户的服务请求。UDP服务器由于只提供无连接服务,不使用listen系统调用。
服务器紧接着就调用accept,以便把远端客户进程发来的连接请求提取出来。系统调用accept的一个变量就是要指明从哪一个套接字发起的连接。

并发方式工作的服务器

图4 并发方式工作的服务器


任意时刻服务器中总是存在一个主服务器进程和零个或多个从属服务器进程。
主服务器进程用原来的套接字接收连接请求,从服务器进程用新创建的套接字和相应的客户端建立连接。

客户端的情况:当客户端调用socket创建套接字之后,客户进程就调用connect,以便和远端服务器建立连接(这是主动打开,相当于客户端发起连接请求)。在connect系统调用中,客户必须指明远端的IP地址和端口号。

2、数据传输阶段

客户和服务器都使用send系统调用传送数据,使用recv系统调用接收数据。
通常,客户使用send发送请求,而服务器使用send发送回答。
服务器使用recv接收客户用send调用发送的请求。客户在发完请求后用recv接收回答。

调用send需要三个参数:数据要发往的套接字描述符、要发送的数据的地址 以及 数据的长度。
调用recv需要三个参数:要使用的套接字描述符、缓存地址 以及 缓存空间的长度。

3、连接释放阶段

一旦客户或服务器结束使用套接字,就把套接字撤销。调用close释放连接和撤销套接字。


图5、socket系统调用顺序

注意UDP服务器提供无连接服务,因此不使用listen 和 accept 系统调用

记住上面的客户端和服务器端调用顺序,之后,进行网络编程只需要把精力放在上层逻辑上面。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值