基于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 ...
随机推荐
- ThinkPHP集锦
使用frame搭建页面:不要引入静态的html文件,应该在Action的方法中填写 例:<frame name="menu" src="{:U(GROUP_NAME ...
- js中Object.defineProperty()和defineProperties()
在介绍js中Object.defineProperty()和defineProperties()之前,我们了解下js中对象两种属性的类型:数据属性和访问器属性. 数据属性 数据属性包含一个数据的位置, ...
- JavaScript是什么
JavaScript是一种解释型语言而不是编译型语言,它往往被认为是一种脚本语言,而不被看作是一种真正的编程语言.也就是说,脚本语言比较简单,它们是非程序员所使用的编程语言. 如果一个程序员对Java ...
- [20190611]记录一下github的基本用法
本文记录如何使用github创建项目并上传代码,因为有一段时间没用github了,中途又重装了系统,今天重新使用一下. 然后特地做简要记录: 1. 创建SSH Key SSH Key指一般在C:\Us ...
- 织梦dedecms后台登陆密码充值工具
下载后解压,根据自己语言版本,把文件radminpass.php放入网站根目录下执行即可 点击下载:织梦dedecms后台登陆密码充值工具
- LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 .NET 4.5 installed Visual Studio 2012 Release Preview
Error 'LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt' after ...
- Python3+Selenium3+webdriver学习笔记14(等待判断 鼠标事件 )
!/usr/bin/env python -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记14(等待判断 鼠标事件 )'''from selenium im ...
- selenium报错信息-- Python 中 'unicodeescape' codec can't decode bytes in position XXX: trun错误解决方案
本以为是缺少utf-8造成的错误,但是加完这个还是报错,于是在网上百度了一下是因为上传的路劲粗无偶导致的 正确的写法是把路劲中“\”变为“\\”,或者在路劲的开头加上“r”,或者在路劲的开头加上“r” ...
- Kail安装后的配置
安装完Kail系统后进行简单的几项配置可以让使用更方便 VMware安装Kail系统这里就不介绍了,大家可以参考这个博客:http://www.cnblogs.com/xuanhun/p/568831 ...
- 洛谷 P2827 蚯蚓
题目描述 本题中,我们将用符号\lfloor c \rfloor⌊c⌋表示对c向下取整,例如:\lfloor 3.0 \rfloor= \lfloor 3.1 \rfloor=\lfloor 3.9 ...