不多说了,先上个图:

从上面的图中可以看出来,基于TCP协议进行通讯可以大致分成以下几个阶段:

1. 首先是在服务器端, TCP Sever调用socket(), bind(), listen()完成初始化。然后调用accept()阻塞等待,处于监听端口的状态。

2. 客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等待服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,

同时应答一个ACK段,服务器收到后从accept()返回。这也就是传说中的TCP三次握手,如下图所示:

TCP 三次握手有一种形象的理解,大家去买手机的时候总要试试手机的通话功能吧, 这时你会走远和你的朋友通话看看质量是否可靠,一般是不是这样:

  • 喂, 听的到吗? (Client)
  • 听的到, 你听的到吗 ? (Server)
  • 嗯, 我也听的到 (Client)

那么就能保证通话质量是OK的, TCP协议也是一样, 通过规定了双方的应答保证了连接的可靠性。

3. 完成三次握手(TCP three way handshake ) TCP Server与TCP Client就建立起了可靠的连接。此后就是Server与Client 数据传输的过程了。因此,服务器从accept()返回

后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待,这时客户端调用write()发送请求给服务器,服务器收到后从read()返回,对客户端的请求进行处理,在

此期间客户端调用read()阻塞等待服务器的应答,服务器调用write()将处理结果发回给客户端,再次调用read()阻塞等待下一条请求,客户端收到后从read()返回,发送下一条请

求,如此循环下去。

4. 关闭连接的过程。 如果客户端没有更多的请求了,就调用close()关闭连接,就像写端关闭的管道一样,服务器的read()返回0,这样服务器就知道客户端关闭了连接,也调用

close()关闭连接。注意,任何一方调用close()后,连接的两个传输方向都关闭,不能再发送数据了。如果一方调用shutdown()则连接处于半关闭状态,仍可接收对方发来的数

据。

贴一个简易的TCP Sever与TCP Client的实现:

 /***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : server.c */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : lab1 */
/* MODULE NAME : server */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2014/12/01 */
/* DESCRIPTION : This is a server program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2014/12/01
*
*/ #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(void)
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
char recv_buf[MAXLINE];
char *send_buf;
char str[INET_ADDRSTRLEN];
int i, n; listenfd = socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd,); printf("Accepting connections ...\n");
cliaddr_len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
while()
{
n = read(connfd, recv_buf, MAXLINE);
if(n == )
{
printf("the client has been closed , please restart again\n");
break;
}
printf("received from %s at PORT %d ",(char *)inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));
//print the recv_buf on the terminal
write(STDOUT_FILENO, recv_buf, n);
printf("\n"); send_buf = "你好世界";
write(connfd, send_buf, strlen(send_buf));
}
close(connfd); }
 /***********************************************************/
/* Copyright (C) SA14226214, USTC, 2014-2015 */
/* */
/* FILE NAME : server.c */
/* PRINCIPAL AUTHOR : GaoZhipeng */
/* SUBSYSTEM NAME : lab1 */
/* MODULE NAME : server */
/* LANGUAGE : C */
/* TARGET ENVIRONMENT : ANY */
/* DATE OF FIRST RELEASE : 2014/12/01 */
/* DESCRIPTION : This is a server program */
/***********************************************************/ /*
*Revision log:
*
*Ceated by GaoZhipeng, 2014/12/01
*
*/ #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h> #define MAXLINE 80
#define SERV_PORT 8000 int main(int argc, char *argv[])
{
struct sockaddr_in servaddr;
char buf[MAXLINE];
int sockfd, n; sockfd = socket(AF_INET, SOCK_STREAM, ); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
servaddr.sin_port = htons(SERV_PORT); connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); printf("input you message (q to exit): "); //ŽÓ±ê׌ÊäÈëÉ豞ÖжÁÈ¡×Ö·ûŽ®ÐŽÈëbuf
while(fgets(buf, MAXLINE, stdin) != NULL) {
if(buf[] == 'q' && strlen(buf) == )
{
break;
}
write(sockfd, buf, strlen(buf)); n = read(sockfd, buf, MAXLINE);
if(n == )
{
printf("the connect side has been closed. please run it again\n");
exit();
}
write(STDOUT_FILENO, "Response from server : ", sizeof("Response from server : "));
write(STDOUT_FILENO, buf, n);
printf("\ninput you message (q to exit): ");
}
close(sockfd);
return ;
}

一个简单的MakeFile :

/*           makefile               */
all :
gcc server.c -o server
gcc client.c -o client clean :
rm server client

基于TCP协议的网络通讯流程的更多相关文章

  1. 闲来无事,写个基于TCP协议的Socket通讯Demo

    .Net Socket通讯可以使用Socket类,也可以使用 TcpClient. TcpListener 和 UdpClient类.我这里使用的是Socket类,Tcp协议. 程序很简单,一个命令行 ...

  2. 基于TCP协议的网络编程

    TCP通信协议是一种可靠的传输层协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成虚拟网络链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信.Java使用Socke ...

  3. 学习笔记——网络编程3(基于TCP协议的网络编程)

    TCP协议基础 IP协议是Internet上使用的一个关键协议,它的全称是Internet Protocol,即Internet协议,通常简称IP协议.   使用ServerSocket创建TCP服务 ...

  4. Java网络编程三--基于TCP协议的网络编程

    ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状体 Socket accept():如果接收到客户端的连接请求,该方法返回一个与客户端对应Socket ...

  5. 浅析C#基于TCP协议的SCOKET通信

    TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实 ...

  6. Learning-Python【28】:基于TCP协议通信的套接字

    什么是 Socket Socket 是应用层与 TCP/IP 协议通信的中间软件抽象层,它是一组接口.在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Sock ...

  7. [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]

    [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...

  8. 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现

    一.客户端/服务器架构(C/S架构)                                                即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...

  9. 网络编程之TCP三次握手与四次挥手、基于TCP协议的套接字编程

    目录 TCP三次握手和四次挥手 背景描述 常用的熟知端口号 TCP概述 TCP连接的建立(三次握手) TCP四次挥手 如果已建立连接,客户端突然断开,会怎么办呢? 基于TCP协议的套接字编程 什么是S ...

随机推荐

  1. 「干货分享」模块化编程和maven配置实践一则

    ​ 封面 说到模块化编程,对我个人而言首先起因于团队协作的需要,也就是组织架构结构特点来决定,而不是跟风求得自我认同,看看我们团队的组织结构: ​ 其中: 基础平台部职责: 1.AI实验室:语音,图像 ...

  2. 给Visual Studio更换皮肤和背景图

    1.先安装更换皮肤的插件 VS菜单栏里面找到:工具>扩展和更新>联机>搜索: Theme Editor 下载并安装: 安装后先不着急重启VS 然后,安装可更改背景图片的插件:工具&g ...

  3. Spring Aspect 获取请求参数

    切片(Aspect)也就是Spring AOP 实现Aspect的主要步骤: 1.在哪里切入 .在哪个方法起作用 .什么时候起作用 2.起作用的时候执行什么处理逻辑 下面是代码实现 /** * 切片A ...

  4. uvm_reg_map——寄存器模型(八)

    所有的寄存器都需要地址,都需要加入到地址列表中 //-------------------------------------------------------------------------- ...

  5. LoadRunner创建脚本和场景流程

    1)脚本创建流程创建脚本->选择协议-设置录制选项-录制脚本-停止录制-优化脚本(去掉无用内容)-强化脚本(注释.代码结构调整.参数化.检查点.事物.关联)-调试脚本(观察日志) 2)场景设置的 ...

  6. javascript日期函数

    时间对象是一个我们经常要用到的对象,无论是做时间输出.时间判断等操作时都与这个对象离不开.除开JavaScript中的时间对象外,在VbScript中也有许多的时间对象,而且非常好用.下面还是按照我们 ...

  7. Maven settings.xml配置详解

    首先:Maven中央仓库的搜索全部公共jar包的地址是,http://search.maven.org/ ===Maven基础-默认中央仓库============================== ...

  8. solver

    slover中有type,用于优化算法的选择,有6种: Stochastic Gradient Descent (type: “SGD”), AdaDelta (type: “AdaDelta”), ...

  9. String java

    https://www.golinuxcloud.com/java-interview-questions-answers-experienced-2/ 75. What is the meaning ...

  10. PAT (Basic Level) Practise (中文)-1020. 月饼 (25)

    http://www.patest.cn/contests/pat-b-practise/1020 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量. ...