Socket编程学习记录
从大一开始就反复接触到Socket这个词,但是一直没有好好的了解一下这方面的东西。
今天学习并整理了一下相关内容。
####1.socket概念
(1)Socket到底是什么?
一句话:Socket是进程通讯的一种方式。
Socket实现的进程通讯不同于信号量、共享内存的本地进程通讯,它提供给我们的是网络上远程地址的主机上的某个进程的通讯。
Socket机制提供的是网络进程通讯。那么具体到一台主机上的Socket编程中的某个Socket实例就可以理解为:IP地址+进程端口号,一个Socket实例等同于网络访问中的标识符,类似于文件标识符,它直接定位到某台主机上的某个进程。
因此网络通讯可以抽象为两台主机上的两个Socket的简单IO操作。
(2)Socket有什么作用?
简化基于CS模式的网络进程通讯,忽略信息传递的复杂过程。在创建本地Socket并获取远程Socket建立通信后,网络进程通讯就等同于对本地文件的简单IO操作,每次传递信息仅需要读写Socket即可。
注意:我看了很多文章提到Socket就一定是TCP那一套。后来又查了一些资料:Socket只是网络通讯的一个管道,它是TCP/IP协议族的应用层抽象,因此不管是TCP还是UDP或者是其它的什么协议都是可以通过Socket来完成的。Socket仅仅是运输数据的一个管道,至于管道里的数据怎么运,有什么格式和规则,那才是协议关心的事情。
####2.Socket编程基础
以下介绍Socket编程的基础函数。
以下均为C语言接口。
Socket编程中Client和Server有很大区别,需要注意,以下均标注。
(1)创建Socket (Client\Server)
创建一个socket实例
int socket(int domain,int type,int protocol);
domain 协议族 IPV4 IPV6 等
type socket类型 ??
protocol 指定协议 使用TCP、UDP、STCP等
type和protocol不能随意组合 有些特定的要求
和打开文件类似,返回值是一个socket标识符
(2)手动绑定地址 (Server)
把地址族中的特定地址赋给socket,用来手动指定socket绑定的地址(如IP+端口号)
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
sockfd socket标识符
addr 指向要绑定给sockfd的协议 如ipv4
addrlen 地址的长度 32位或者16位
通常服务器在启动的时候都会绑定一个众所周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。
(3)进入监听状态 (Server)
服务器调用socket()和bind()以后调用listen()监听socket收到的请求。
int listen(int sockfd,int backlog);
sockfd socket标识符
backlog 这个socket可以排队的最大连接个数
(4)发起一个连接请求(Client)
客户端调用socket()后直接使用connect连接服务器。
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
sockfd socket标识符
addr 服务器的socket地址
addrlen socket地址的长度
(4)接受请求 (Server)
服务器监听到请求后调用accept()接收请求,接收完后即可进行网络IO操作,操作方式等同于操作本地文件
int accept(int sockfd,struct *addr,socklen_t *addrlen);
三个参数:socket标识符 客户端的协议地址 协议地址长度
返回值是一个全新的标识符,代表和客户端通信的TCP客户端。
注意,这里的sockfd是服务器上的某个socket,而不是客户端的。客户端在服务器上的Socket标识符由内核负责创建,在通讯被关闭后自动销毁。
(5)读写Socket中的数据 (Client\Server)1
2
3
4
5read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()
这是Socket提供的几个IO函数。
它们的使用方式和一般的IO函数类似,其中最常用的是recvmsg()/sendmsg()
这一对函数。
由于这几个函数参数比较多,具体的说明留置使用时查询文档。这里不再解释。
(6)关闭Socket (Client\Server)int close(int fd);
和关闭一个文件类似,每次创建完Socket后需要手动关闭回收。