基于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 ...
随机推荐
- 「干货分享」模块化编程和maven配置实践一则
封面 说到模块化编程,对我个人而言首先起因于团队协作的需要,也就是组织架构结构特点来决定,而不是跟风求得自我认同,看看我们团队的组织结构: 其中: 基础平台部职责: 1.AI实验室:语音,图像 ...
- 给Visual Studio更换皮肤和背景图
1.先安装更换皮肤的插件 VS菜单栏里面找到:工具>扩展和更新>联机>搜索: Theme Editor 下载并安装: 安装后先不着急重启VS 然后,安装可更改背景图片的插件:工具&g ...
- Spring Aspect 获取请求参数
切片(Aspect)也就是Spring AOP 实现Aspect的主要步骤: 1.在哪里切入 .在哪个方法起作用 .什么时候起作用 2.起作用的时候执行什么处理逻辑 下面是代码实现 /** * 切片A ...
- uvm_reg_map——寄存器模型(八)
所有的寄存器都需要地址,都需要加入到地址列表中 //-------------------------------------------------------------------------- ...
- LoadRunner创建脚本和场景流程
1)脚本创建流程创建脚本->选择协议-设置录制选项-录制脚本-停止录制-优化脚本(去掉无用内容)-强化脚本(注释.代码结构调整.参数化.检查点.事物.关联)-调试脚本(观察日志) 2)场景设置的 ...
- javascript日期函数
时间对象是一个我们经常要用到的对象,无论是做时间输出.时间判断等操作时都与这个对象离不开.除开JavaScript中的时间对象外,在VbScript中也有许多的时间对象,而且非常好用.下面还是按照我们 ...
- Maven settings.xml配置详解
首先:Maven中央仓库的搜索全部公共jar包的地址是,http://search.maven.org/ ===Maven基础-默认中央仓库============================== ...
- solver
slover中有type,用于优化算法的选择,有6种: Stochastic Gradient Descent (type: “SGD”), AdaDelta (type: “AdaDelta”), ...
- String java
https://www.golinuxcloud.com/java-interview-questions-answers-experienced-2/ 75. What is the meaning ...
- PAT (Basic Level) Practise (中文)-1020. 月饼 (25)
http://www.patest.cn/contests/pat-b-practise/1020 月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量. ...