Socket介绍

进程之间是怎么进行通信的

在学习Socket之前我们先来了解了解进程之间是怎么进行通信的。

本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类:

  • 消息传递(管道、FIFO、消息队列)
  • 同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)
  • 共享内存(匿名的和具名的)
  • 远程过程调用(Solaris门和Sun RPC)

但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

使用TCP/IP协议的应用程序通常采用应用编程接口:UNIX BSD的套接字(socket)和UNIX System V的TLI(已经被淘汰),来实现网络进程之间的通信。就目前而言,几乎所有的应用程序都是采用socket,而现在又是网络时代,网络中进程通信是无处不在,这就是我为什么说“一切皆socket”。

概述

什么是Socket?

讲解1

上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭),这些函数我们在后面进行介绍。
socket一词的起源在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的,撰写者为Stephen Carr、Steve Crocker和Vint Cerf。根据美国计算机历史博物馆的记载,Croker写道:“命名空间的元素都可称为套接字接口。一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:“这比BSD的套接字接口定义早了大约12年。”

讲解2

socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。

我们把插头插到插座上就能从电网获得电力供应,同样,为了与远程计算机进行数据传输,需要连接到因特网,而 socket 就是用来连接到因特网的工具。

socket 的典型应用就是 Web 服务器和浏览器:浏览器获取用户输入的 URL,向服务器发起请求,服务器分析接收到的 URL,将对应的网页内容返回给浏览器,浏览器再经过解析和渲染,就将文字、图片、视频等元素呈现给用户。

学习 socket,也就是学习计算机之间如何通信,并编写出实用的程序

UNIX/Linux 中的 socket 是什么?

在 UNIX/Linux 系统中,为了统一对各种硬件的操作,简化接口,不同的硬件设备也都被看成一个文件。对这些文件的操作,等同于对磁盘上普通文件的操作。

你也许听很多高手说过,UNIX/Linux 中的一切都是文件!那个家伙说的没错。

为了表示和区分已经打开的文件,UNIX/Linux 会给每个文件分配一个 ID,这个 ID 就是一个整数,被称为文件描述符(File Descriptor)。例如:

  • 通常用 0 来表示标准输入文件(stdin),它对应的硬件设备就是键盘;
  • 通常用 1 来表示标准输出文件(stdout),它对应的硬件设备就是显示器。

UNIX/Linux 程序在执行任何形式的 I/O 操作时,都是在读取或者写入一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数,它的背后可能是一个硬盘上的普通文件、FIFO、管道、终端、键盘、显示器,甚至是一个网络连接。

请注意,网络连接也是一个文件,它也有文件描述符!你必须理解这句话。

我们可以通过 socket() 函数来创建一个网络连接,或者说打开一个网络文件,socket() 的返回值就是文件描述符。有了文件描述符,我们就可以使用普通的文件操作函数来传输数据了,例如:

  • 用 read() 读取从远程计算机传来的数据;
  • 用 write() 向远程计算机写入数据。

你看,只要用 socket() 创建了连接,剩下的就是文件操作了,网络编程原来就是如此简单!

Window 系统中的 socket 是什么?

Windows 也有类似“文件描述符”的概念,但通常被称为“文件句柄”。因此,本教程如果涉及 Windows 平台将使用“句柄”,如果涉及 Linux 平台则使用“描述符”。

与 UNIX/Linux 不同的是,Windows 会区分 socket 和文件,Windows 就把 socket 当做一个网络连接来对待,因此需要调用专门针对 socket 而设计的数据传输函数,针对普通文件的输入输出函数就无效了。

如何标识一个Socket

一个Socket是由一个五元组来标识的

一个socket是由一个五元组来唯一标志的,即(protocol,server_ip, server_port, client_ip, client_port)。
只要该五元组中任何一个值不同,则其代表的socket就不同。这里忽略协议的区别,在同一协议的基础上,服务器端的listen socket的端口可以看成(server_ip, server_port, ***, ***),其中*是通配符,**它跟任何一个client_ip, client_port值都不同,可以简单看成是(0, 0)对,当然实现不是这样的。这样在服务器端accept之后,返回的连接socket的四元组就是(server_ip, server_port, client_ip, client_port),这里的client_ip,client_port因连接的客户端的不同而不同。所以accept返回的socket和listen socket是不同的,不同之处就在于四元组中的客户端ip和port,而服务器端的server_ip和server_port还是相同的,也就是accpet()函数返回的新的socket描述符的端口和listen端口是一样的。可以使用getsockname()函数来查看它们之间的不同。
要写网络程序就必须用Socket,这是程序员都知道的。而且,面试的时候,我们也会问对方会不会Socket编程?一般来说,很多人都会说,**Socket编程基本就是listen,accept以及send,write等几个基本的操作。是的,就跟常见的文件操作一样,只要写过就一定知道。 **
对于网络编程,我们也言必称TCP/IP,似乎其它网络协议已经不存在了。对于TCP/IP,我们还知道TCP和UDP,前者可以保证数据的正确和可靠性,后者则允许数据丢失。最后,我们还知道,在建立连接前,必须知道对方的IP地址和端口号。除此,普通的程序员就不会知道太多了,很多时候这些知识已经够用了。最多写服务程序的时候,会使用多线程来处理并发访问。
我们还知道如下几个事实:
  1.一个指定的端口号不能被多个程序共用。比如,如果IIS占用了80端口,那么Apache就不能也用80端口 了。
  2.很多防火墙只允许特定目标端口的数据包通过。
  3.服务程序在listen某个端口并accept某个连接请求后,会生成一个新的socket来对该请求进行处理。

为什么一个端口可以同时与多个客户端通信

于是,一个困惑了我很久的问题就产生了。如果一个socket创建后并与80端口绑定后,是否就意味着该socket占用了80端口呢?如果是这样的,那么当其accept一个请求后,生成的新的socket到底使用的是什么端口呢(我一直以为系统会默认给其分配一个空闲的端口号)?如果是一个空闲的端口,那一定不是80端口了,于是以后的TCP数据包的目标端口就不是80了–防火墙一定会阻止其通过的!实际上,我们可以看到,防火墙并没有阻止这样的连接,而且这是最常见的连接请求和处理方式。我的不解就是,为什么防火墙没有阻止这样的连接?它是如何判定那条连接是因为connet80端口而生成的?是不是TCP数据包里有什么特别的标志?或者防火墙记住了什么东西?
后来,我又仔细研读了TCP/IP的协议栈的原理,对很多概念有了更深刻的认识。**比如,在TCP和UDP同属于传输层,共同架设在IP层(网络层)之上。而IP层主要负责的是在节点之间(End to End)的数据包传送,这里的节点是一台网络设备,比如计算机。因为IP层只负责把数据送到节点,而不能区分上面的不同应用,所以TCP和UDP协议在其基础上加入了端口的信息,端口于是标识的是一个节点上的一个应用。除了增加端口信息,UPD协议基本就没有对IP层的数据进行任何的处理了。**而TCP协议还加入了更加复杂的传输控制,比如滑动的数据发送窗口(Slice Window),以及接收确认和重发机制,以达到数据的可靠传送。不管应用层看到的是怎样一个稳定的TCP数据流,下面传送的都是一个个的IP数据包,需要由TCP协议来进行数据重组。
所以,我有理由怀疑,防火墙并没有足够的信息判断TCP数据包的更多信息,除了IP地址和端口号。而且,我们也看到,所谓的端口,是为了区分不同的应用的,以在不同的IP包来到的时候能够正确转发。
TCP/IP只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。就像操作系统会提供标准的编程接口,比如Win32编程接口一样,TCP/IP也必须对外提供编程接口,这就是Socket编程接口–原来是这么回事啊!
** 在Socket编程接口里,设计者提出了一个很重要的概念,那就是socket。**这个socket跟文件句柄很相似,实际上在BSD系统里就是跟文件句柄一样存放在一样的进程句柄表里。**这个socket其实是一个序号,表示其在句柄表中的位置。**这一点,我们已经见过很多了,比如文件句柄,窗口句柄等等。这些句柄,其实是代表了系统中的某些特定的对象,用于在各种函数中作为参数传入,以对特定的对象进行操作–这其实是C语言的问题,在C++语言里,这个句柄其实就是this指针,实际就是对象指针啦。
现在我们知道,socket跟TCP/IP并没有必然的联系。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以,socket的出现只是可以更方便的使用TCP/IP协议栈而已,其对TCP/IP进行了抽象,形成了几个最基本的函数接口。比如create,listen,accept,connect,read和write等等。
现在我们明白,如果一个程序创建了一个socket,并让其监听80端口,其实是向TCP/IP协议栈声明了其对80端口的占有。以后,所有目标是80端口的TCP数据包都会转发给该程序(这里的程序,因为使用的是Socket编程接口,所以首先由Socket层来处理)。所谓accept函数,其实抽象的是TCP的连接建立过程accept函数返回的新socket其实指代的是本次创建的连接,而一个连接是包括两部分信息的,一个是源IP和源端口,另一个是宿IP和宿端口。所以,accept可以产生多个不同的socket,而这些socket里包含的宿IP和宿端口是不变的,变化的只是源IP和源端口。这样的话,这些socket宿端口就可以都是80,而Socket层还是能根据源/宿对来准确地分辨出IP包和socket的归属关系,从而完成对TCP/IP协议的操作封装!而同时,防火墙的对IP包的处理规则也是清晰明了,不存在前面设想的种种复杂的情形。

服务器端与客户端的五元组是如何确定的

第2节Socket介绍相关推荐

  1. 网络编程 socket介绍

    Socket介绍 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对 ...

  2. socket介绍--数据的编码与解码

    socket 介绍 思考 不同电脑上的进程之间如何通信? 首先通过 IP 地址找到网络中对应的电脑,然后通过传输协议和端口号来确定这个进程(运行起来 的软件),那么数据如何传输需要使用 socket ...

  3. 深黑黑板风格感恩节主题介绍PPT模板

    模板介绍 深黑黑板风格感恩节主题介绍PPT模板.一套节日PPT幻灯片模板,内含黑色,橙色多种配色,风格设计,动态播放效果,精美实用. 希望下面这份精美的PPT模板能给你带来帮助,温馨提示:本资源使用P ...

  4. nodeJS入门(五)之socket介绍

    Socket 1.1.socket介绍 1.2.socket的通讯流程 1.3.webSocket 1.4.webSocket对象介绍 1.4.1.属性 1.4.2.事件 1.4.3.方法 1.5.使 ...

  5. iPhone 实用技巧 之 快速使用iTools安装ipa软件。本节简单介绍如何使用iTools安装在iPhone上安装ipa软件

    iPhone 实用技巧 之 快速使用iTools安装ipa软件.本节简单介绍如何使用iTools安装在iPhone上安装ipa软件,具体如下 目录 iPhone 实用技巧 之 快速使用iTools安装 ...

  6. 火云开发课堂 - 《Shader从入门到精通》系列 第一节:Shader介绍与工程搭建

    <Shader从入门到精通>系列在线课程 第一节:Shader介绍与工程搭建 视频地址:http://edu.csdn.net/course/detail/1441/22665?auto_ ...

  7. 【Linux系统编程】socket介绍

    1. socket 介绍 所谓 socket(套接字),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象(端到端通信).一个套接字就是网络上进程通信的一端,给应用层进程提供了利用网络协议交 ...

  8. WebSocket和socket介绍

    B/S结构的软件项目中有时客户端需要实时的获得服务器消息,但默认HTTP协议只支持请求响应模式,这样做可以简化Web服务器,减少服务器的负担,加快响应速度,因为服务器不需要与客户端长时间建立一个通信链 ...

  9. WIFI学习一(socket介绍)

    一.什么是socket socket译为"插座",在计算机通信领域,socket被翻译为"套接字",它是计算机之间进行通信的一种约定或一种方式.通过这种方式,一 ...

最新文章

  1. MySQL面试题 | 附答案解析(五)
  2. 纯生信发ISME的一次试炼
  3. Linux16.04配置CUDA8.0+CUDNNV5.1
  4. ant-design-vue 环境搭建及入门
  5. Oracle date 插入显示公元前日期
  6. Windows下DNS ID欺骗的原理与实现
  7. 如何在Python Django中处理用户身份验证
  8. 关于Python局部变量和全局变量必须知道的几句话
  9. 开源dns软件PowerDNS BIND9 mydns
  10. stm32显示flash下载失败_Flash download failed-Cortex-M3的原因及解决办法
  11. Android 调用Gmail发送邮件
  12. 语音识别—声学模型训练(前向-后向算法)
  13. 关于C++ 里struct 和 class的区别
  14. ITSS-信息技术服务运行维护标准符合性认证
  15. EXCEL中空白单元格如何快速填充为0
  16. 怎么让计算机休眠的时候不断网,Windows10系统如何让电脑睡眠状态也不断网?
  17. IBM Power小型机用液晶面板屏查看或设置HMC
  18. syntax error, unexpected ‘array‘ (T_ARRAY)
  19. 使用mdadm创建RAID
  20. 一个研究生毕业后的职业规划

热门文章

  1. 服务器远程不上怎么办?
  2. BZOJ1507 [NOI2003]Editor
  3. sudoku me_Sudoku,一个完整的MFC应用程序。 第7部分
  4. convert ps pcl emf wmf to pdf files using ghostscript
  5. 【4月比赛合集】19场可报名的「创新应用」和「程序设计」大奖赛,任君挑选!
  6. 使用python库relate搭建LMS学习管理系统
  7. window10 1060 caffe 安装
  8. HTML+JS 动态爱心效果,表白神器,装逼特效
  9. mysql修改database名_MySQL中修改database的名字
  10. 抖音上面那些暴力引流套路!赚到月入过万!