近期研究下socket,发现自己还是有非常多不明确的地方,索性沉下心来,从最基础開始学习,開始看起,如今对自己的学习做下小小总结,以便和大家分享,如有谬误,敬请指正。

原创文章,转载请注明出处:http://blog.csdn.net/jessonlv

TCP/IP

在学习socket之前,先回想下TCP/IP协议。

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机怎样连入因特网及数据怎样再它们之间传输的标准,从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族。不同于ISO模型的七个分层,TCP/IP协议參考模型把全部的TCP/IP系列协议归类到四个抽象层中:

应用层:tftp、http、snmp、smtp、dns、telnet等

传输层:tcp和udp

网络层:IP ICMP OSPF EIGRP IGMP

链路层:SLIP CSLIP PPP MTU

看图说话:



在TCP/IP协议中两个因特网主机通过两个路由器和相应的层连接。各主机上的应用通过一些数据通道相互运行读取操作:

socket

怎样唯一标识一个进程

利用三元组:ip地址、协议、port号。事实上这是TCP/IP协议提供的解决方案,网络层的ip地址能够唯一标识网络中的主机。传输层的协议+port能够唯一标识主机中的应用程序。
在能唯一标识进程后,就能够进行socket通信了,socket是基于unix的一种“open--write/read--close”模式的一种实现。它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。
看图说话:
注:socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,server和client各自维护一个"文件",在建立连接打开后,能够向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

socket的通信流程

socket是"打开—读/写—关闭"模式的实现,以使用TCP协议通讯的socket为例,其交互流程大概是这样子的





server依据地址类型(ipv4,ipv6)、socket类型、协议创建socket





server为socket绑定ip地址和port号





serversocket监听port号请求,随时准备接收client发来的连接,这时候server的socket并没有被打开





client创建socket





client打开socket,依据serverip地址和port号试图连接serversocket





serversocket接收到clientsocket请求,被动打开,開始接收client请求,直到client返回连接信息。这时候socket进入堵塞状态,所谓堵塞即accept()方法一直到client返回连接信息后才返回,開始接收下一个client谅解请求





client连接成功,向server发送连接状态信息





serveraccept方法返回,连接成功





client向socket写入信息





server读取信息





client关闭





server端关闭

有名的三次握手

在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接:
第一次握手:client尝试连接server,向server发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,client进入SYN_SEND状态等待server确认





第二次握手:server接收clientsyn包并确认(ack=j+1),同一时候向client发送一个SYN包(syn=k),即SYN+ACK包,此时server进入SYN_RECV状态





第三次握手:第三次握手:client收到server的SYN+ACK包,向server发送确认包ACK(ack=k+1),此包发送完毕,client和server进入ESTABLISHED状态,完毕三次握手





定眼一看,serversocket与clientsocket建立连接的部分事实上就是大名鼎鼎的三次握手:


socket编程API

主要參考java api:
int socket(int domain, int type, int protocol);

依据指定的地址族、数据类型和协议来分配一个socket的描写叙述字及其所用的资源。

domain:协议族,经常使用的有AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE当中AF_INET代表使用ipv4地址

type:socket类型,经常使用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等

protocol:协议。经常使用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等

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

把一个地址族中的特定地址赋给socket

sockfd:socket描写叙述字,也就是socket引用

addr:要绑定给sockfd的协议地址

addrlen:地址的长度


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

int listen(int sockfd, int backlog);
监听socket

sockfd:要监听的socket描写叙述字

backlog:对应socket能够排队的最大连接个数 

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

连接某个socket

sockfd:client的socket描写叙述字

addr:server的socket地址

addrlen:socket地址的长度

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

TCPserver监听到client请求之后,调用accept()函数取接收请求

sockfd:server的socket描写叙述字

addr:client的socket地址

addrlen:socket地址的长度


ssize_t read(int fd, void *buf, size_t count);

读取socket内容

fd:socket描写叙述字

buf:缓冲区

count:缓冲区长度


ssize_t write(int fd, const void *buf, size_t count);

向socket写入内容,事实上就是发送内容

fd:socket描写叙述字

buf:缓冲区

count:缓冲区长度


int close(int fd);

socket标记为以关闭 ,使对应socket描写叙述字的引用计数-1,当引用计数为0的时候,触发TCPclient向server发送终止连接请求。



初步理解socket的更多相关文章

  1. javascript 原型及原型链的初步理解

    最近折腾了好久,终于是把js里面的原型和原型链做了个初步的理解: 在这里,我打个比喻: 我(child),我妈constructor(构造函数)生了我:别人问我老妈跟谁生的我,于是此时我妈会指向我爸爸 ...

  2. Spring学习笔记--环境搭建和初步理解IOC

    Spring框架是一个轻量级的框架,不依赖容器就能够运行,像重量级的框架EJB框架就必须运行在JBoss等支持EJB的容器中,核心思想是IOC,AOP,Spring能够协同Struts,hiberna ...

  3. 简单理解Socket

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  4. Graph Cuts初步理解

    一些知识点的初步理解_8(Graph Cuts,ing...) Graph cuts是一种十分有用和流行的能量优化算法,在计算机视觉领域普遍应用于前背景分割(Image segmentation).立 ...

  5. [转]简单理解Socket

    简单理解Socket 转自 http://www.cnblogs.com/dolphinX/p/3460545.html  题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公 ...

  6. socket.io,理解socket.io

    原文:http://www.cnblogs.com/xiezhengcai/p/3957314.html 要理解socket.io ,不得不谈谈websocket 在html5之前,因为http协议是 ...

  7. 【转】 简单理解Socket

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  8. 【转】简单理解socket

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  9. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

随机推荐

  1. DNS之XX记录

    DNS服务器里有两个比较重要的记录.一个叫SOA记录(起始授权机构) 一个叫NS(Name Server)记录(域名服务器)关于这两个记录,很多文章都有解释,但是很多人还是很糊涂.我现在通俗的解释一下 ...

  2. Git分支管理小结

    分支管理命令 每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支.HEAD严格来说不是指向提交,而是指向mas ...

  3. 木块问题(UVa101)

    题目具体描述见:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_prob ...

  4. Templated Helper Methods(二)

      1.Label and Display Elements   2.Whole-Model Templated Helpers     3.Using Metadata to Control Edi ...

  5. LoadRunner中参数的设置

    LoadRunner中参数的设置 参数个数:10个 tester1.tester2.tester3…tester10 迭代次数:2次 场景设置(一):Sequential+Each Iteration ...

  6. Failed to lookup view 'error'

    这个问题在npm run dev进行本地开发时,没有问题.但是在npm run build后,生产服务器上部署时出现问题. 我对本地的路径排查,发现写的没有问题 所以我去了生产的文件夹看路径 我去了s ...

  7. C# 字符串提取数字

    转自:http://www.cnblogs.com/dolphin-gjh/p/6121792.html 一.使用正则表达式 1 string str = "sztq数字提取123sztq数 ...

  8. NumPy 新知

    import numpy as np a = np.arange(5) a array([0, 1, 2, 3, 4]) 增加一个维度: b = a[:, None] c = a[:,np.newax ...

  9. 深度学习应用系列(四)| 使用 TFLite Android构建自己的图像识别App

    深度学习要想落地实践,一个少不了的路径即是朝着智能终端.嵌入式设备等方向发展.但终端设备没有GPU服务器那样的强大性能,那如何使得终端设备应用上深度学习呢? 所幸谷歌已经推出了TFMobile,去年又 ...

  10. POJ 3228 [并查集]

    题目链接:[http://poj.org/problem?id=3228] 题意:给出n个村庄,每个村庄有金矿和仓库,然后给出m条边连接着这个村子.问题是把所有的金矿都移动到仓库里所要经过的路径的最大 ...