网络编程学习笔记一

发布 2021-05-02 07:21:28 阅读 3498

网络编程学习笔记一:socket编程

目录(?)1. 网络中进程之间如何通信。

2. 什么是socket

1. socket一词的起源。

3. socket的基本操作。

1. 31socket函数。

2. 32bind函数。

1. 网络字节序与主机字节序。

3. 33listenconnect函数。

4. 34accept函数。

5. 35readwrite等函数。

6. 36close函数。

4. socket中tcp的三次握手建立连接详解。

5. socket中tcp的四次握手释放连接详解。

6. 一个例子实践一下。

7. 动动手。

1. unix domain

一切皆socket!”

话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。

—有感于实际编程和开源项目研究。

我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与web服务器通信的?当你用qq聊天时,qq进程怎么与服务器或你好友所在的qq进程通信?这些都得靠socket?

那什么是socket?socket的类型有哪些?还有socket的基本函数,这些都是本文想介绍的。

本文的主要内容如下:

1、网络中进程之间如何通信?

2、socket是什么?

3、socket的基本操作。

o 3.1、socket()函数。

o 3.2、bind()函数。

o 3.3、listen()、connect()函数。

o 3.4、accept()函数。

o 3.5、read()、write()函数等。

o 3.6、close()函数。

4、socket中tcp的三次握手建立连接详解。

5、socket中tcp的四次握手释放连接详解。

6、一个例子(实践一下)

7、留下一个问题,欢迎大家回帖回答!!!

1、网络中进程之间如何通信?

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

消息传递(管道、fifo、消息队列)

同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量)

共享内存(匿名的和具名的)

远程过程调用(solaris门和sun rpc)

但这些都不是本文的主题!我们要讨论的是网络中进程之间如何通信?首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!

在本地可以通过进程pid来唯一标识一个进程,但是在网络中这是行不通的。其实tcp/ip协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

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

2、什么是socket?

上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于unix,而unix/linux基本哲学之一就是“一切皆文件”,都可以用“打开open –>读写write/read –>关闭close”模式来操作。我的理解就是socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写io、打开、关闭),这些函数我们在后面进行介绍。

socket一词的起源。

在组网领域的首次使用是在2023年2月12日发布的文献ietf rfc33中发现的,撰写者为stephen carr、steve crocker和vint cerf。根据美国计算机历史博物馆的记载,croker写道:“命名空间的元素都可称为套接字接口。

一个套接字接口构成一个连接的一端,而一个连接可完全由一对套接字接口规定。”计算机历史博物馆补充道:“这比bsd的套接字接口定义早了大约12年。

”3、socket的基本操作。

既然socket是“open—write/read—close”模式的一种实现,那么socket就提供了这些操作对应的函数接口。下面以tcp为例,介绍几个基本的socket接口函数。

3.1、socket()函数。

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

socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建一个socket描述符(socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都有用到它,把它作为参数,通过它来进行一些读写操作。

正如可以给fopen的传入不同参数值,以打开不同的文件。创建socket的时候,也可以指定不同的参数创建不同的socket描述符,socket函数的三个参数分别为:

domain:即协议域,又称为协议族(family)。常用的协议族有,af_inet、af_inet6、af_local(或称af_unix,unix域socket)、af_route等等。

协议族决定了socket的地址类型,在通信中必须采用对应的地址,如af_inet决定了要用ipv4地址(32位的)与端口号(16位的)的组合、af_unix决定了要用一个绝对路径名作为地址。

type:指定socket类型。常用的socket类型有,sock_stream、sock_dgram、sock_raw、sock_packet、sock_seqpacket等等(socket的类型有哪些?

)。protocol:故名思意,就是指定协议。常用的协议有,ipproto_tcp、ipptoto_udp、ipproto_sctp、ipproto_tipc等,它们分别对应tcp传输协议、udp传输协议、stcp传输协议、tipc传输协议(这个协议我将会单独开篇讨论!

)。注意:并不是上面的type和protocol可以随意组合的,如sock_stream不可以跟ipproto_udp组合。当protocol为0时,会自动选择type类型对应的默认协议。

当我们调用socket创建一个socket时,返回的socket描述字它存在于协议族(address family,af_xxx)空间中,但没有一个具体的地址。如果想要给它赋值一个地址,就必须调用bind()函数,否则就当调用connect()、listen()时系统会自动随机分配一个端口。

3.2、bind()函数。

正如上面所说bind()函数把一个地址族中的特定地址赋给socket。例如对应af_inet、af_inet6就是把一个ipv4或ipv6地址和端口号组合赋给socket。

intbind(intsockfd, conststructsockaddr *addr, socklen_taddrlen);

函数的三个参数分别为:

sockfd:即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这个描述字绑定一个名字。

addr:一个conststructsockaddr *指针,指向要绑定给sockfd的协议地址。这个地址结构根据地址创建socket时的地址协议族的不同而不同,如ipv4对应的是:

structsockaddr_in ;

/* internet address. *

structin_addr {

uint32_t s_addr; /address in network byte order */

ipv6对应的是:

struct sockaddr_in6 {

sa_family_tsin6_family; /af_inet6 */

in_port_tsin6_port; /port number */

uint32_t sin6_flowinfo; /ipv6 flow information */

struct in6_addr sin6_addr; /ipv6 address */

uint32_t sin6_scope_id; /scope id (new in 2.4) *

struct in6_addr {

unsignedchar s6_addr[16]; ipv6 address */

unix域对应的是:

#define unix_path_max 108

structsockaddr_un {

sa_family_tsun_familyaf_unix */

charsun_path[unix_path_max]; pathname */

通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。

网络字节序与主机字节序。

主机字节序就是我们平常说的大端和小端模式:不同的cpu有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。引用标准的big-endian和little-endian的定义如下:

a) little-endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

网络编程学习笔记

一 tcp网络编程流程。1 client端。初始化socket 解析服务器地址。connect send2 server端。初始化soket用于监听。解析地址。bind地址,绑定本机的地址。listen监听socket accept接收。select轮训判断是否有数据更新。二 函数学习。1 主机字节...

dom编程学习笔记

一 dom编程。a 基本概念。dom document object model 文档对象模型。其实就是将一些标记型的文档以及文档中的内容当成对象。为什么要将这些文档以及其中的标签封装成对象呢?因为可以在对象中定义其属性和行为,可以方便操作这些对象。b dom在封装标记型文档时,有三层模型 dom1...

编程学习笔记 初级

1 alt enter快捷键 cmd窗口最大化。2 显示命令行帮助信息。3 color 设置默认的cmd窗口前景和背景颜色。4 dir 显示目录中的文件和子目录列表 例 dir d 5 cd 显示当前目录名或改变当前目录 例 cd d 表示上一级目录 表示当前目录 tab键 自动匹配 表示根目录。6...