关于socket编程的简单认识

面试的时候面试官问到“请问你是否了解socket编程?”
说实话,我是知道一些函数的,但是具体的实现我不了解,并且工作中也基本上没用到。所以我回答了“不是很了解,只是校招的时候知道一些函数”,现在想想,还是自己学习的不够系统,漏洞百出啊。

今天,简简单单学习下socket编程。

1.什么是socket编程?
socket是一种网络通信的技术。
上一篇博客复习了三次握手和四次挥手,但是没有复习到五大层及其所拥有的一些常见的协议。现在举例说明几个协议。

层级 协议
应用层 HTTP/FTP/DNS/SMTP
传输层 TCP/UDP
网络层 IP/ICMP/ARP
数据链路层 ARP/RARP
物理层

五层架构展示完了,此时,就想socket通信,是在哪一层上或者哪一层和哪一层之间呢。
从博客
处摘要了该博主一张很生动的结构图:
关于socket编程的简单认识_第1张图片

很明显,socket通信位于应用层和传输层之间。流程大致为:传输层为socket层提供服务,socket层再为应用层提供服务。之前复习过了TCP三次握手,socket通信也是通过类似三次握手的形式实现的通信,现在直接看socket层是如何实现的吧。仍然是从上面博主的博客中得到这样一张简明扼要的结构图
关于socket编程的简单认识_第2张图片
这个三次握手的过程实质上时已经创建了socket通道之后的数据传输的过程,在这之前我们需要创建socket,并且利用socket中提供的方法来实现客户端和服务器之间的通信。
流程图:来自于博客
关于socket编程的简单认识_第3张图片
关于socket编程的简单认识_第4张图片
看一下socket各个函数的功能及使用。
//不要忘记包含头文件
1.socket()函数

#include 
/*
param domain 协议族,如AF_INET,AF_INET6等
param type   指定socket(套接口)类型,如SOCK_STREAM,SOCK_DGRAM
param protocol 指定协议(一般为0,根据type有默认值),如IPPROTO_TCP,IPPROTO_UDP等
*/
int socket(int domain, int type, int protocol);

2.bind函数

#include 
/*
sockfd 		socket()函数的返回值
address 	指向特定协议的地址结构指针
addLen 		address所指向的结构体的长度
*/

int bind(int sockfd, const struct sockaddr* address, socklen_t addLen);

3.listen()函数
该函数只在TCP服务器中使用,和客户端无关。

#include 
/*
sockfd		当前创建的套接口的标识
backlog		后台等待连续队列的最大限制值
*/

int listen(int sockfd, int backlog);

4.connect()函数
该函数有客户端调用,和服务器建立连接

#include 
/*
sockfd		客户端创建的套接口标识
addr		指向套接口地址结构的指针
addrlen 	addr指向结构体的大小
*/
int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);

5.accept()函数
该函数由TCP服务器调用

#include 
/*
sockfd		服务器	创建的套接口标识
addr		返回客户端的协议地址
addrlen 	协议地址的长度
*/

int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);

6.close()函数
close函数用于关闭套接口,服务器端和客户端均调用。

#include 
//sockfd	套接口的标识
int close(int sockfd);

客户端和服务器建立了通信之后。此时我们就可以把socket的返回值(sockfd)当做文件描述符来使用。

今天补充两个重要的函数,也是面试的时候问到的函数。
1.write函数

//write将缓存buf中的bytes个字节大小的写入sockfd,成功时候返回写的字节数大小,失败时-1.
size_t write(int sockfd, void* buf, size_t bytes)
//返回值大于0时,表示写了部分或者全部数据。
//小于0 时表示出错。

2.read函数

size_t read(int fd,void *buf,size_t nbyte)
//从fd中读取内容.
//返回值大于0时,表明实际所读的字节数
//返回值为0,表示已经读到文件的结束了,
//返回值小于0,表示出现了错误。如果错误为EINTR说明读是由中断引起 的, 如果是ECONNREST表示网络连接出了问题.

当然,还有recv和send函数用于读写操作。

你可能感兴趣的:(网络编程)