socket 套接字 ---- 基础

socke相当于插座,也就是接口

一、基本概念
socket使用之前,首先要申请一个socket对象。同时要知道对方的socket,然后请求连接,双方建立连接,然后就可以进行收发数据。

socket利用网络间通信设施进行进程通信,对通信的细节不用关心。
【socket五元组:协议、本地地址、本地端口、远程地址、远程端口

socket面向客户-服务器模型而设计,针对用户和服务器程序提供不同的socket系统调用。
客户端随机申请一个socket,服务器拥有全局socket,巧妙的解决了 进程之间建立通信连接的问题。
二、套接字的分类
1、流式套接字:SOCK_STREAM
流式套接字可以提供可靠地,面向连接的通讯流
流式套接字使用TCP协议,TCP保证了你的数据传输是正确的,并且是有顺序的。
socket 套接字 ---- 基础
编程流程
首先通过调用socket()创建一个套接字,然后调用bind()绑定IP地址和端口号,再调用listen()做好监听的准备,并规定请求队列长度,之后调用accept()来接受连接。客户在建立socket之后们就可以调用connect()来想服务器发起连接。连接一旦建立,客户端和服务器端之间就可以通过read()和write()来发送接收数据。最后待数据传送结束后,双方调用close()关闭套接字。

2、数据报套接字:SOCK_DGRAM
数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证可靠,无差错。底层使用UDP协议
不可靠的表现:
(1)如果你发送了一个数据报,它可能不会到达
(2)它可能会以不同的顺序到达
(3)如果它到达了,它包含的数据中可能存在错误
socket 套接字 ---- 基础
3、原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议实现的测试等。主要用于一些协议开发,进行比较底层的操作,它功能强大,但是没有流式套接字和数据报套接字使用方便。

为什么说是无连接
因为UDP不像流式套接字那样维护一个打开的连接,你只需要把数据打成一个包,把远程的IP粘上去,然后把这个包发送出去。这个过程是不需要建立连接的。

数据包既然会丢失,怎么样才能保证程序能够正常工作呢?
每个使用UDP的程序都要有自己的对数据进行确认的协议,例如,TFTP
对于每一个发送出去的数据包,远程在接受到之后都要会送一个数据包告诉本地程序:“我已经拿到了”。如果数据包的发送者5秒内没有得到回应,他就重发这个数据包直到数据包接受者回送了“ACK”信号。

一个套接字到底是什么?
套接字是 通过 标准的文件描述符和其他的程序通讯的一个方法

在Linux系统中,任何对 I/O 的操作,都是通过读或者写一个文件描述符来实现的。 一个文件描述符只是一个简单的整形数值,代表一个被打开的文件,LINUX系统中,一切皆文件。

如何得到套接字?
首先调用系统调用socket(),它返回一个套接字描述符,然后就可以通过对这个套接字描述符进行一些操作:系统函数send()和recv()
write()和read()也可以对套接字描述符进行操作,但是send()和recv可以对网络数据传输进行更好的控制
【具体解析,详见博客中的另外一篇具体的文章】

一个套接字是如何在网络上传输数据的?
数据被分成一个个包,包的数据头被第一次协议加上第一层协议数据;然后整个包被下层协议再次包装,再这之后数据包又被下层协议包装,最后被最底层的硬件层包装上最后一层信息
接收端的计算机收到这个数据的时候,硬件首先剥去数据包中的信息头,然后内核再剥去IP和Tcp 的头,最后把数据交给上层应用程序,

参考书目:《Linux网络编程》