介绍套接字之前,我们先看一下传输层的协议TCP与UDP:

TCP协议与UDP协议的区别

首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UDP协议的

区别,我觉得这是没有从本质上弄清楚网络通信!

TCP/IP协议是一个协议簇。里面包括很多协议的。UDP只是其中的一个。之所以命名为TCP/IP协议,因为TCP,IP协议是

两个很重要的协议,就用他两命名了。

TCP/IP协议集包括应用层,传输层,网络层,网络访问层。

其中应用层包括:

超文本传输协议(HTTP):万维网的基本协议.

文件传输(TFTP简单文件传输协议):

远程登录(Telnet),提供远程访问其它主机功能,它允许用户登录

internet主机,并在这台主机上执行命令.

网络管理(SNMP简单网络管理协议),该协议提供了监控网络设备的方法,以及配置管理,统计信息收集,性能管理及安全管

理等.

域名系统(DNS),该系统用于在internet中将域名及其公共广播的网络节点转换成IP地址.

其次网络层包括:

Internet协议(IP)

Internet控制信息协议(ICMP)

地址解析协议(ARP)

反向地址解析协议(RARP)

最后说网络访问层:网络访问层又称作主机到网络层(host-to-network).网络访问层的功能包括IP地址与物理地址硬件

的映射,以及将IP封装成帧.基于不同硬件类型的网络接口,网络访问层定义了和物理介质的连接.

当然我这里说得不够完善,TCP/IP协议本来就是一门学问,每一个分支都是一个很复杂的流程,但我相信每位学习软件

开发的同学都有必要去仔细了解一番。

下面我着重讲解一下TCP协议和UDP协议的区别。

TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建

立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,只简单的描述下这三次对

话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A

发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发

?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对

话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。

详细点说就是:(文章部分转载http://zhangjiangxing-gmail-com.iteye.com,主要是这个人讲解得很到位,的确很

容易使人理解!)

TCP三次握手过程

1 主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B ,向主机B 请求建立连接,通过这个数据段,

主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我.

2 主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两

件事:

我已经收到你的请求了,你可以传输数据了;你要用哪佧序列号作为起始数据段来回应我

3 主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:"我已收到回复,我现在要开始传输实际数

据了

这样3次握手就完成了,主机A和主机B 就可以传输数据了.

3次握手的特点

没有应用层的数据

SYN这个标志位只有在TCP建产连接时才会被置1

握手完成后SYN标志位被置0

TCP建立连接要进行3次握手,而断开连接要进行4次

1 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求

2  主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1

3 由B 端再提出反方向的关闭请求,将FIN置1

4 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.

由TCP的三次握手和四次断开可以看出,TCP使用面向连接的通信方式,大大提高了数据通信的可靠性,使发送数据端

和接收端在数据正式传输前就有了交互,为数据正式传输打下了可靠的基础

名词解释

ACK  TCP报头的控制位之一,对数据进行确认.确认由目的端发出,用它来告诉发送端这个序列号之前的数据段

都收到了.比如,确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时

会要求重传数据,保证数据的完整性.

SYN  同步序列号,TCP建立连接时将这个位置1

FIN  发送端完成发送任务位,当TCP完成数据传输需要断开时,提出断开连接的一方将这位置1

TCP的包头结构:

源端口 16位

目标端口 16位

序列号 32位

回应序号 32位

TCP头长度 4位

reserved 6位

控制代码 6位

窗口大小 16位

偏移量 16位

校验和 16位

选项  32位(可选)

这样我们得出了TCP包头的最小长度,为20字节。

UDP(User Data Protocol,用户数据报协议)

(1) UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的

数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能

力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

(2) 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户

机传输相同的消息。

(3) UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

(4) 吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合

并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送

UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

UDP的包头结构:

源端口 16位

目的端口 16位

长度 16位

校验和 16位

小结TCP与UDP的区别:

1.基于连接与无连接;

2.对系统资源的要求(TCP较多,UDP少);

3.UDP程序结构较简单;

4.流模式与数据报模式 ;

5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。TCP失败就重传,UDP不会

接下来,我们再看看工作在应用层的套接字编程:

套接字是一种使用标准UNIX文件描述符(file descriptor)与其他程序通信的方式。套接字可以看作是处于不同主机之间的两个程序的通信连接端点。一方面程序将要传输的信息写入套接字中,而另一方面则通过读取套接字内的数据来获得传输的信息。

图1  套接字通信示意图

图1所示为使用套接字进行通信的示意图。假设存在两台主机A与B,在主机A中存在进程C,主机B中存在进程D,当进程C需要将数据送到进程D时,首先将数据写到套接字中,而进程D可以通过读取套接字来获得进程C发送的信息。

在网络中,不同计算机是通过IP地址来区分的,也就 是说,要将数据由主机A发送到主机B,只要知道主机B的IP地址就可以确定数据要发送的目的地。但是,在主机A与B中不可能只有进程C和进程D两个进程。 主机B在收到主机A发送来的数据后,如何才能确定该数据是发送给进程D?因此,还需要某种标识信息,用于描述网络通信数据发往的进程。TCP/IP协议提 出了协议端口的概念,用于标识通信的进程。

当进程与某个端口绑定后,操作系统会将收到的给该端 口的数据送往该进程。与文件描述符类似,每个端口都有被称为端口号的整数类型的标识符,该标识符用于区分不同的端口。不同协议可以使用相同的端口号进行数 据传输。例如,TCP使用了344的端口号,UDP同样可以使用344端口号进行数据传输。

端口号为一个16位的无符号整数,其取值范围为0~65535。低于256的端口被作为系统的保留端口号,主要用于系统进程的通信,不在这一范围的端口号被称为自由端口号,可以由进程自由使用。

主要看一下客户端的:

retval = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));

//(struct sockaddr*)&servaddr里 是服务器的地址,表示连接到服务器的某一个地址

套接字

ret = getaddrinfo(pSrvName, NULL, &hostInfo, &pAddrInfo);

getaddrinfo函数能够处理名字到地址以及服务到端口这两种转换,返回的是一个sockaddr结构的链表而不是一个地址清单。这些sockaddr结构随后可由套接口函数直接使用

int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );

参数说明

hostname:一个主机名或者地址串(IPv4的点分十进制串或者IPv6的16进制串)

service:服务名可以是十进制的端口号,也可以是已定义的服务名称,如ftp、http等

hints:可以是一个空指针,也可以是一个指向某个addrinfo结构体的指针,调用者在这个结构中填入关于期望返回的信息类型的暗示。举例来说:指定的服务既可支持TCP也可支持UDP,所以调用者可以把hints结构中的ai_socktype成员设置成SOCK_DGRAM使得返回的仅仅是适用于数据报套接口的信息。

result:本函数通过result指针参数返回一个指向addrinfo结构体链表的指针。

返回值:0——成功,非0——出错

在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol

通常服务器端在调用getaddrinfo之前,ai_flags设置AI_PASSIVE,用于bind;主机名nodename通常会设置为NULL,返回通配地址[::]。

如果nodename是本机名,servname为NULL,则根据操作系统的不同略有不同,地址列表加以返回

struct sockaddr{

unsigned short sa_family;

char sa_data[14]

};

sa_family:用于指定地址族,如果是TCP/IP通信,该值取PF_INET。sa_data:用于保存套接字的IP地址和端口号信息

struct sockaddr_in {

   short int sin_family;

   unsigned short int sin_port;

   struct in_addr sin_addr;

   unsigned char sin_zero[8];

  };

l     sin_family:用于指定地址族。

l     sin_port:套接字通信的端口号。

l     sin_addr:通信的IP地址。

l     sin_zero[8]:用以填充0,保持与struct sockaddr同样大小。

由于sockaddr数据结构与sockaddr_in数据结构的大小是相同的,指向sockaddr_in的指针可以通过强制转换,转换成指向sockaddr结构的指针。

int socket(int domain, int type, int protocol);

socket函数用于创建通信的套接字,并返回该套接字的文件描述符。参数domain指定了通信域,该参数用于选择通信协议族参数type用于指定套接字的类型。套接字类型除了前面提到的流套接字、数据报套接字及原始套接字外,还有其他的几种类型参数protocol用于指定套接字使用的通信协议。正常情况下,对于给定的协议族,只有单一的协议支持特定的套接字类型。这时,只要将protocol参数设置为0即可

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

connect函数将使用参数sockfd中的套接字连接到参数serv_addr中指定的服务器。参数addrlen为serv_addr指向的内存空间大小。

如果参数sockfd的类型为SOCK_DGRAM,serv_addr参数为数据报发往的地址,且将只接收该地址的数据报。如果sockfd的类型为SOCK_STREAM或SOCK_SEQPACKET,调用该函数将连接serv_addr中的服务器地址。

ssize_t send(int s, const void *buf, size_t len, int flags);

send函数用于将信息发送到指定的套接字文件描述 符中。该函数只能用于已经建立连接的socket通信中,即只用于面向连接的通信中。参数s为要发送数据的套接字文件描述符。buf参数为指向要发送数据 的指针。len为要发送数据的长度。flag参数可以包含如下的参数

ssize_t recv(int s, void *buf, size_t len, int flags);

recv函数用于从指定套接字中获取发送的消息。与send函数一样,该函数只能用于已经建立连接的socket通信中,即只用于面向连接的通信中。参数s为要读取信息的套接字文件描述符。buf参数为指向要保存数据缓冲区的指针。而len为该缓存的最大长度。

使用套接字除了可以实现网络间不同主机间的通信外,还可以实现同一主机的不同进程间的通信,且建立的通信是双向的通信。这里所指的使用套接字实现进程间通信,是由将通信域指定为PF_UNIX来实现的

AF 表示ADDRESS FAMILY 地址族,PF 表示PROTOCOL FAMILY 协议族,但这两个宏定义是一样的,所以使用哪个都没有关系。Winsock2.h中#define AF_INET 2,#define PF_INET AF_INET,所以在windows中AF_INET与PF_INET完全一样。而在Unix/Linux系统中,在不同的版本中这两者有微小差别。对于BSD,是AF,对于POSIX是PF。UNIX系统支持AF_INET,AF_UNIX,AF_NS等,而DOS,Windows中仅支持AF_INET,它是网际网区域。

AF_INET(又称 PF_INET)是 IPv4 网络协议的套接字类型,AF_INET6 则是 IPv6 的;而 AF_UNIX 则是 Unix 系统本地通信。选择AF_INET 的目的就是使用 IPv4 进行通信。因为 IPv4 使用 32 位地址,相比 IPv6 的 128 位来说,计算更快,便于用于局域网通信。而且 AF_INET 相比 AF_UNIX 更具通用性,因为 Windows 上有 AF_INET 而没有 AF_UNIX。

2.

SOCKET是进程间通信的一种方式,这个时候socket的创建、绑定、连接时的参数是与网络上不同主机间的通信不同的,比如对于socketaddr的使用,进程间通信使用的是sockaddr_un。而主机间的通信使用的是sockadd_in

connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);

if(connect_fd < 0)

{

perror("client create socket failed");

return 1;}

//set server sockaddr_un

srv_addr.sun_family = AF_UNIX;

strcpy(srv_addr.sun_path, UNIX_DOMAIN);

//connect to server

ret = connect(connect_fd, (struct sockaddr*)&srv_addr, sizeof(srv_addr));

至于服务器的,参考下图(流套接字通信示意图):

数据报套接字(udp)示意图:

附笔者笔记:

1.网络通信tcp与udp

2.套接字编程

转载于:https://www.cnblogs.com/yuweifeng/p/5641262.html

Linux之socket套接字编程20160704相关推荐

  1. 基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

    基于UDP协议 的socket套接字编程 1.UDP套接字简单示例 1.1服务端 import socketserver = socket.socket(socket.AF_INET,socket.S ...

  2. 【Linux】网络套接字编程

    前言 在掌握一定的网络基础,我们便可以先从代码入手,利用UDP协议/TCP协议进行编写套接字程序,明白网络中服务器端与客户端之间如何进行连接并且通信的. 目录 一.了解源目的IP.端口.网络字节序.套 ...

  3. 自学Python 58 Socket套接字编程 (一)

    Python Socket套接字编程 (一) 文章目录 Python Socket套接字编程 (一) 一.库 Socket 内置函数和属性 二.Python中的socket通信逻辑   Socket又 ...

  4. Linux IPv6 UDP套接字编程示例

    udp ipv6套接字编程和ipv4接口类似,参数略有不同,流程都包括创建套接字.绑定地址.发送等. 下面是一个udp ipv6 demo, 包括创建ipv6套接字.绑定地址和发送数据等. 首先先在l ...

  5. linux sock_raw原始套接字编程

    sock_raw原始套接字编程可以接收到本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的.一共可以有3种方式创建这种socket   1.socket(AF_INET, SOCK_R ...

  6. Socket套接字编程

    一.Socket是什么 1. socket套接字: socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",都可以用"打开open –> ...

  7. TCP与UDP协议、socket套接字编程、通信相关操作(cs架构软件)、TCP黏包问题及解决思路

    OSI七层协议 传输层 1.PORT协议:前面讲过 2.TCP协议与UDP协议:规定了数据传输所遵循的规则(数据传输能够遵循的协议有很多,TCP和UDP是较为常见的两个) TCP协议 基于TCP传输数 ...

  8. TCP与UDP协议,socket套接字编程,通信相关操作

    文章目录 TCP与UDP协议 TCP协议 ==三次握手== ==四次挥手== UDP协议 TCP与UDP的区别 应用层 socket套接字 代码优化 循环通信 半连接池 粘包问题 TCP与UDP协议 ...

  9. TCP Socket套接字编程 附源码

    TCP 最主要的特点 TCP 是面向连接的运输层协议.应用程序在使用 TCP 协议之前,必须先建立 TCP 连接.在传送数据完毕后,必须释放已经建立的 TCP 连接 每一条 TCP 连接只能有两个端点 ...

最新文章

  1. c++ primer,友元函数上的一个例子(By Sybase)
  2. DNS and Bind (一)
  3. linux 扫描仪 程序,Linux桌面的4种扫描工具
  4. 为什么祖国没有农历生日? | 今日最佳
  5. java基础—几种for循环编程思想
  6. PVFS2 1.4.0的安装、配置与性能测试
  7. Netty工作笔记0015---MappedByteBuffer使用
  8. 传感器原理及工程应用第4版
  9. js 封装websocket (包括心跳检测,断线重连等)
  10. 空间三点确定圆心坐标及半径
  11. 解决验证码不显示问题
  12. 微信扫二维码挪车小程序开发制作功能
  13. linux技术--MySQL分区
  14. 罗宾斯管理学13版pdf_罗宾斯管理学13版答案pdf
  15. np.zeros()生成3维
  16. mysql一个字段为空时使用另一个字段排序
  17. python中一般使用几个空格表示缩进_为什么Python pep-8强烈建议使用标签上的空格来缩进?...
  18. 十年期国债利率倒数与A股PE中位数走势
  19. can和could的用法_情态动词can和could用法详解
  20. (信贷风控九)行为评分卡模型python实现(详细代码+注释+讲解)

热门文章

  1. centos下为firefox安装flash插件的几种方法
  2. html标签的赋值与取值
  3. 区块链热度飙升 BAT抢先布局话语权争夺战开打
  4. token拦截器阻止连接_如何防止广告拦截器阻止您的分析数据
  5. 使用Fiddler进行HTTP流量分析
  6. Spring Cloud应用开发(一:使用Eureka注册服务)
  7. h3c交换机端口加入vlan命令_华为交换机批量加入 Vlan 方法
  8. PL/SQL编程:用for循环算出5的阶乘
  9. gitee查看当前账号_upic+gitee图床,自由书写Markdown
  10. jquery 获取Select option 选择的Text和Value