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 系统调用

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

时间: 2024-08-05 09:14:39

linux socket网络编程详解的相关文章

Java网络编程详解

Java网络编程详解 http://blog.csdn.net/he90227/article/details/39184247 Java网络编程详解

linux socket网络编程 常用函数及头文件

转自:http://blog.chinaunix.net/u3/102500/showart_2065640.html 一 三种类型的套接字: 1.流式套接字(SOCKET_STREAM) 提供面向连接的可靠的数据传输服务.数据被看作是字节流,无长度限制.例如FTP协议就采用这种. 2.数据报式套接字(SOCKET_DGRAM) 提供无连接的数据传输服务,不保证可靠性. 3.原始式套接字(SOCKET_RAW) 该接口允许对较低层次协议,如IP,ICMP直接访问. 二 基本套接字系统调有有如下一

Linux Socket 网络编程

Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后,过段时间不看,重新拾起这些知识的时候又要从头开始,所以,在这里做个笔记也算是做个模板,以后可以直接从某一个阶段开始接着玩... 1. socket套接字介绍 socket机制其实就是包括socket, bind, listen, connect, accept等函数的方法,其通过指定的函数实现不同

【linux高级程序设计】(第十三章)Linux Socket网络编程基础 2

BSD Socket网络编程API 创建socket对象 int socket (int __domain, int __type, int __protocol) :成功返回socket文件描述符,失败返回-1. 参数1:socket对象使用的地址簇或协议簇  常用的有PF_LOCAL(本机通信).PF_INET(IPv4协议簇).PF_INET6(IPv6协议簇) 参数2:socket的类型.常见有:面向连接的数据流方式:面向无连接的数据报方式 参数3:标识采用哪一种协议,0表示默认. 绑定

linux系统socket通信编程详解函数

linux socket编程之TCP与UDP TCP与UDP区别 TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端. UDP---用户数据报协议,是一个简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地.由于UDP在传输数据报前不用在客户和服

Linux 网络编程详解九

TCP/IP协议中SIGPIPE信号产生原因 1.假设客户端socket套接字close(),会给服务器发送字节段FIN: 2.服务器接收到FIN,但是没有调用close(),因为socket有缓存区,所以服务器仍然可以向客户端发送数据. 3.如果这种状态下服务器向客户端发送数据,将会引起TCP/IP协议进行RST段重置,导致服务器向当前进程发送SIGPIPE信号, SIGPIPE信号的默认动作是关闭当前进程. 所以在网络编程中必须要捕捉SIGPIPE信号,因为不确定哪个端会突然close().

【linux高级程序设计】(第十三章)Linux Socket网络编程基础

IP地址定义: struct in_addr{ __u32 s_addr; }; in_addr_t  inet_addr (__const char * __cp) :把点分十进制IP地址字符串转换为32位IP地址(网络存储顺序). in_addr_t inet_network (__const char * __cp) :把点分十进制IP地址字符串转换为32位IP地址(主机字节顺序). char * inet_ntoa (struct in_addr_in) :把32位网络字节顺序的IP地址

【linux高级程序设计】(第十三章)Linux Socket网络编程基础 4

网络调试工具 tcpdump 功能:打印指定网络接口中与布尔表达式匹配的报头信息 关键字: ①类型:host(默认).net.port host 210.27.48.2 //指明是一台主机 net 202.0.0.0 //指明是一个网络 port 23 //指明端口号 ②确认传输方向:src. dst. dst or src. dst and src src 210.27.48.2 //ip包中源地址为此值 dst net 202.0.0.0 //目的网络地址是202.0.0.0 ③协议关键字:

Linux 网络编程详解一

IPv4套接字地址结构 struct sockaddr_in { uint8_t sinlen;(4个字节) sa_family_t sin_family;(4个字节) in_port_t sin_port;(2个字节) struct in_addr sin_addr;(4个字节) char sin_zero[8]; }; sin_len:整个sockaddr_in结构体的长度,部分Linux内核版本没有该成员 sin_family:指定该地址家族,一般设置为AF_INET(使用TCP,UDP协