一、基于TCP协议的网络程序

下图是基于TCP协议的客户端/服务器程序的一般流程:

服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回。

数据传输的过程:

建立连接后,TCP协议提供全双工的通信服务,但是一般的客户端/服务器程序的流程是由客户端主动发起请求,服务器被动处理请求,一问一答的方式。因此,服务器从accept()返回后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待,这时客户端调用write()发送请求给服务器,服务器收到后从read()返回,对客户端的请求进行处理,在此期间客户端调用read()阻塞等待服务器的应答,服务器调用write()将处理结果发回给客户端,再次调用read()阻塞等待下一条请求,客户端收到后从read()返回,发送下一条请求,如此循环下去。

如果客户端没有更多的请求了,就调用close()关闭连接,就像写端关闭的管道一样,服务器的read()返回0,这样服务器就知道客户端关闭了连接,也调用close()关闭连接。注意,任何一方调用close()后,连接的两个传输方向都关闭,不能再发送数据了。如果一方调用shutdown()则连接处于半关闭状态,仍可接收对方发来的数据。

在学习socket API时要注意应用程序和TCP协议层是如何交互的:

*应用程序调用某个socket函数时TCP协议层完成什么动作,比如调用connect()会发出SYN段

*应用程序如何知道TCP协议层的状态变化,比如从某个阻塞的socket函数返回就表明TCP协议收到了某些段,再比如read()返回0就表明收到了FIN段

补充一下,其实TCP 共有11种状态,上图没有出现的CLOSING 状态,当双方同时关闭连接时会出现此状态,替换掉FIN_WAIT2状态。

二、基本socket函数

1、socket函数

包含头文件<sys/socket.h>
功能:创建一个套接字用于通信
原型:int socket(int domain, int type, int protocol);
参数
domain :指定通信协议族(protocol family),AF_INET、AF_INET6、AF_UNIX等
type:指定socket类型,流式套接字SOCK_STREAM,数据报套接字SOCK_DGRAM,原始套接字SOCK_RAW
protocol :协议类型,IPPROTO_TCP等;一般由前两个参数就决定了协议类型,设置为0即可。
返回值:成功返回非负整数, 它与文件描述符类似,我们把它称为套接口描述字,简称套接字。失败返回-1

2、bind函数

包含头文件<sys/socket.h>
功能:绑定一个本地地址到套接字
原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:socket函数返回的套接字
addr:要绑定的地址
addrlen:地址长度
返回值:成功返回0,失败返回-1

3、listen函数

包含头文件<sys/socket.h>
功能:将套接字用于监听进入的连接
原型:int listen(int sockfd, int backlog);
参数
sockfd:socket函数返回的套接字
backlog:已完成三次握手的最大连接个数
返回值:成功返回0,失败返回-1

一般来说,listen函数应该在调用socket和bind函数之后,调用函数accept之前调用。
对于给定的监听套接口,内核要维护两个队列:
1、已由客户发出并到达服务器,服务器正在等待完成相应的TCP三路握手过程
2、已完成连接的队列

如下图所示:

Be careful to differentiate between TCP
accepting a connection and placing it on this queue, and the application
taking the accepted connection off this queue.

Keep in mind that this
backlog value specifies only the maximum number of
queued connections for one listening end point, all of which have
already been accepted by TCP and are waiting to be accepted by the
application. This backlog has no effect whatsoever on the maximum
number of established connections allowed by the system, or on
the number of clients that a concurrent server can handle concurrently.

If there is not room on the queue for
the new connection, TCP just ignores the received SYN. Nothing is sent
back (i.e., no RST segment). If the listening server doesn't get around
to accepting some of the already accepted connections
that have filled its queue to the limit, the client's active open will
eventually time out.

In the attempted connection to a
nonexistent host,  how frequently the client’s TCP sends a SYN to try to
establish the connection. The second segment is sent 3s after the
first, the third is sent 6s after the second, the fourth
is sent 12s after the third, and soon. This behavior is called
exponential backoff.

4、accept函数

包含头文件<sys/socket.h>
功能:从已完成连接队列返回第一个连接,如果已完成连接队列为空,则阻塞。
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:服务器套接字
addr:将返回对等方的套接字地址
addrlen:返回对等方的套接字地址长度
返回值:成功返回非负整数,失败返回-1

5、connect函数

包含头文件<sys/socket.h>
功能:建立一个连接至addr所指定的套接字
原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数
sockfd:未连接套接字
addr:要连接的套接字地址
addrlen:第二个参数addr长度
返回值:成功返回0,失败返回-1

参考:

《Linux C 编程一站式学习》

《TCP/IP详解 卷一》

《UNP》

C/S程序的一般流程和基本socket函数的更多相关文章

  1. 【原创】storyboard启动应用程序的大致流程

    storyboard启动应用程序的大致流程 [原创] 转载请注明出处:http://i.cnblogs.com/EditPosts.aspx?postid=5395023 1. 用户点击APP图标—— ...

  2. Ios 程序封装,安装流程

    转:http://www.myexception.cn/operating-system/1436560.html Ios 程序打包,安装流程 一.发布测试,是指将你的程序给   * 你的测试人员,因 ...

  3. vc++深入跟踪MFC程序的执行流程

    在MFC程序设计的学习过程中最令人感到难受,甚至于有时会动摇学习者信心的就是一种对于程序的一切细节都没有控制权的感觉.这种感觉来源于学习者不知道一个MFC程序是如何运行起来的(即一个MFC程序的执行流 ...

  4. JAVA_SE基础——3.Java程序的开发流程

    上一篇,写的是JAVA的环境变量的配置,今天我抽空写篇Java程序的开发流程,下面的教程是我结合书本和毕向东老师的视频写下的心的~ 在没有真正写Java程序前,首先需要了解Java程序的开发过程. S ...

  5. Net Core 使用外部登陆提供程序登陆的流程,以及身份认证的流程

    在Asp.Net Core 中使用外部登陆(google.微博...)   原文出自Rui Figueiredo的博文<External Login Providers in ASP.NET C ...

  6. 深入跟踪MFC程序的执行流程

    来源: http://blog.csdn.net/ljianhui/article/details/8781991 在MFC程序设计的学习过程中最令人感到难受,甚至于有时会动摇学习者信心的就是一种对于 ...

  7. Android开发第一讲之目录结构和程序的执行流程

    1.如何在eclipse当中,修改字体 下面的这种办法,可以更改xml的字体 窗口--首选项--常规--外观--颜色和字体--基本--文本字体--编辑Window --> Preferences ...

  8. php程序的三大流程控制

    php程序的三大流程控制 ①  顺序控制(从上到下.从左到右) ②分支控制 if(条件表达式){ //n多语句 }else if (条件表达式){ //n 多语句 }else if(条件表示式){ / ...

  9. 3-1Java程序的执行流程

    3-1Java程序的执行流程 用记事本写一个简单的程序 存到:E:\java路径下 class HelloImooc{    public static void main(String[] agrg ...

随机推荐

  1. SQL Server’s Storage Top 10 Best Practices

    好文章, 简明扼要. Storage Top 10 Best Practices http://technet.microsoft.com/en-us/library/cc966534.aspx

  2. Linked List Cycle leetcode II java (寻找链表环的入口)

    题目: Given a linked list, return the node where the cycle begins. If there is no cycle, return null. ...

  3. 总结div里面水平垂直居中的实现方法

    最近经常碰到要垂直居中的问题,所以想着总结一下:关于如何设置小盒子在大盒子里面水平垂直方向同时居中的实现方法有很多种,下面仅列举了常用的几种. 首先看一下要实现的效果图及对应的html代码: < ...

  4. JavaScript之深浅拷贝

    数组的浅拷贝 如果是数组,我们可以利用数组的一些方法比如:slice.concat 返回一个新数组的特性来实现拷贝.比如: , true, null, undefined]; var new_arr ...

  5. mybatis的statement的解析与加载(springboot)

    问题 mybatis的xml中的sql语句是启动时生成JDK代理类的时候就生成一次么 调用顺序链 解析xml配置 Reader reader = Resources.getResourceAsRead ...

  6. js生成pdf报表

    由于前台html已经动态生成报表,而且,前台有一个功能,一个date range组件,当你拖动的时候,报表会在不提交到后台的情况下动态变化.因此需要用到js生成生报表: 用到的组件: jquery.j ...

  7. Java从零开始学二十三(集合Map接口)

    一.Map接口 Collection.Set.List接口都属于单值的操作,即:每次只能操作一个对象,而Map与它们不同的是,每次操作的是一对对象,即二元偶对象,Map中的每个元素都使用key à v ...

  8. MySQL 联合索引测试

    搭建测试环境 1:创建表 CREATE TABLE tab_index (id int(5), age int(3), dte datetime); 2:插入测试数据 INSERT INTO tab_ ...

  9. 解决win10 获取不到ip

    1.检查Dhcp服务是否启动 2.关闭防火墙

  10. 检查用户输入信息是否完整(vb.net实现)

        机房收费系统中.在将用户输入的信息封装到实体中作为參数传到B层之前,总要对用户输入的信息进行检查.我将这种检查分为两类: 合法性检查 完整性检查     所谓合法性检查,就是用户输入的信息是否 ...