基于TCP协议的网络通讯流程
不多说了,先上个图:

从上面的图中可以看出来,基于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协议的网络通讯流程的更多相关文章
- 闲来无事,写个基于TCP协议的Socket通讯Demo
.Net Socket通讯可以使用Socket类,也可以使用 TcpClient. TcpListener 和 UdpClient类.我这里使用的是Socket类,Tcp协议. 程序很简单,一个命令行 ...
- 基于TCP协议的网络编程
TCP通信协议是一种可靠的传输层协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成虚拟网络链路.一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信.Java使用Socke ...
- 学习笔记——网络编程3(基于TCP协议的网络编程)
TCP协议基础 IP协议是Internet上使用的一个关键协议,它的全称是Internet Protocol,即Internet协议,通常简称IP协议. 使用ServerSocket创建TCP服务 ...
- Java网络编程三--基于TCP协议的网络编程
ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状体 Socket accept():如果接收到客户端的连接请求,该方法返回一个与客户端对应Socket ...
- 浅析C#基于TCP协议的SCOKET通信
TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程.然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实 ...
- Learning-Python【28】:基于TCP协议通信的套接字
什么是 Socket Socket 是应用层与 TCP/IP 协议通信的中间软件抽象层,它是一组接口.在设计模式中,Socket 其实就是一个门面模式,它把复杂的 TCP/IP 协议族隐藏在 Sock ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- 网络编程----socket介绍、基于tcp协议的套接字实现、基于udp协议的套接字实现
一.客户端/服务器架构(C/S架构) 即C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架 ...
- 网络编程之TCP三次握手与四次挥手、基于TCP协议的套接字编程
目录 TCP三次握手和四次挥手 背景描述 常用的熟知端口号 TCP概述 TCP连接的建立(三次握手) TCP四次挥手 如果已建立连接,客户端突然断开,会怎么办呢? 基于TCP协议的套接字编程 什么是S ...
随机推荐
- 洛谷 P1969 积木大赛
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- winform代码生成器(三)
代码下载 地址 http://pan.baidu.com/s/1nuZjyat 接上面的两篇. 用户有时对 从表的 排版不喜欢,可以因某些字太长,需要拉长一些,有些则需要隐藏. 有什么办法呢? 我的思 ...
- c#的Lambda 表达式
首先看官方的说法: Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数. 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数. Lambda 表达式 ...
- sqlserver 数据库 的数据库个数统计 表个数统计 表的数据量统计(转载)
http://www.cnblogs.com/qinche/archive/2012/08/09/app.html 由于今天要监控数据,急需统计实例中1有多少库2库里有多少表3每个表有多少数据 --将 ...
- querySelector/querySelectorAll
querySelector获取页面I属性D为test的元素: document.getElementById("test"); //or document.querySelecto ...
- 【机器学习实战】第2章 K-近邻算法(k-NearestNeighbor,KNN)
第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法主要是用来进行分类的. KNN 场景 电影可以按照题材分类,那么如何区分 动作片 和 爱情片 呢? 动作 ...
- iOS Automated Tests with UIAutomation
参照:http://blog.manbolo.com/2012/04/08/ios-automated-tests-with-uiautomation#1 UI Automation JavaScri ...
- ComboBox控件“设置 DataSource 属性后无法修改项集合”的解决【转】
编写Winform程序,遇到comboBox的绑定事件和索引项变更事件的冲突问题,就是“设置 DataSource 属性后无法修改项集合”的错误问题,网上查了很多,大多说在索引项变更是进行非空判断,还 ...
- Unity中实现全局管理类的几种方式
(搬运自我在SegmentFault的博客) 如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合 ...
- Memcached笔记之分布式算法
1.根据余数进行分散:离散度高,但是增加或者移除服务器的时候,缓存充足的代价非常大.添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器,从而音像缓存的命中率. 2.Consistent ...