linux&C这两天学到了网络编程这一章,自己写了一个小的”服务器”和”客户端”程序,目的在于简单理解tcp/ip模型,以及要搭建一台简单服务器,服务器和客户端最基本的事情要干什么,这篇博客就这个小程序,也简单分析了自己对”TCP-三次握手”过程的理解。因为初学网络编程,说的不对的地方欢迎大家评论交流。

套接字:
套接字由4部分组成,服务器IP地址和客户端IP地址以及服务器端口号和客户端端口号,是客户端和服务器端传输数据确定线路的保证,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。

首先我们来看服务器端的代码:

#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h> #define MAX_QUEUE_LENGTH 1024 int main(int argc,char *argv[])
{
int sock_fd,conn_fd;
struct sockaddr_in serv_addr,conn_addr;
socklen_t conn_len;
pid_t pid1;
char recv_buf[128];
int ret; //创建套接字
sock_fd = socket(AF_INET,SOCK_STREAM,0);
/*参数分别为(使用IPV4 tcp/ip协议,使用tcp流套接字,
通过前两个参数来确定使用的协议类型,默认为零)*/ //mZ服务器端的套接字进行初始化
memset(&serv_addr,0,sizeof(struct sockaddr_in));
//memset函数将serv_addr 用0进行初始化
serv_addr.sin_family = AF_INET;
/*设置地址类型:对于sin_family,表示用tcp/ip协议编程,
所以此值只能为AF_INEF*/
serv_addr.sin_port = htons(4507);
//设置端口号为4507
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//关于ANADDR——ANY这个宏的解释在下面有,也可以向下面一样设定指定IP
//inet_pton(AF_INET,"XXX.XXX.XXX.XXX",&serv_addr.sin_addr);
//当我只有一块网卡,一个IP,所以也只能设置为自己的ip了 //绑定套接字
bind(sock_fd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr_in));
/*绑定套接字的过程是将我前面创建的套接字与初始化的端口绑定起来, 因为socket只是创建了一个套接字,这个套接字将在哪个端口上工作, 并没有被指定,作为服务器,它的IP和端口一般是固定的,因此我们需要将刚才
初始化的端口和套接字绑定到一起,这时套接字已经完成服务器的ip和端口这一半*/ //将套接字转化成监听套接字
listen(sock_fd,MAX_QUEUE_LENGTH);
//第二个参数比较重要,它是我们服务器已完成套接字队列的长度,accept函数每次
//会从已完成的套接字队列中拿走一个即conn_fd,也就是监听套接字,注意:内核会维护两个队列,
//一个是已完成的套接字队列,一个是未完成的套接字队列,一个套接字完成的过程是在三次握手的
//过程中完成的,是由tcp/ip协议栈完成的 //接受客户端的请求
conn_len = sizeof(struct sockaddr_in);
while(1)
{
conn_fd = accept(sock_fd,(struct sockaddr *)&conn_addr,&conn_len);
//服务器会将客户端的连接消息先放在未完成的队列中,三次握手之后,就到已完成队列中
//conn_fd就是accept返回的叫作连接套接字,它的信息有服务器的端口和IP以及客户的端口和IP,
//监听套接字继续监听,对于新的处理,系统会重新开一个线程处理,自己也可以用进程
printf("accept a new connection,ip:%s\n",inet_ntoa(conn_addr.sin_addr));
pid1 = fork();
if(pid1 == 0)
ret = recv(conn_fd,recv_buf,sizeof(recv_buf),0);
recv_buf[ret-1] = '\0';
}
printf("%s\n",recv_buf);
}

注释中解释了套接字的初始化,建立,绑定,监听的过程,结束之后我们服务器端的工作就做好了,为了检验程序是否正确,运行程序之后我们可以用netstat命令查看我们服务器端是否开启监听模式

$ netstat -apt | grep LISTEN


可以看到4507端口的状态是LISTEN。

在说说INADDR_ANY的作用

INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。举个例子:你的电脑上如果有多块网卡就会有好几个IP,或者说你的服务器有多台主机也会有好多个IP,而如果你的IP会发生变化,比如变多或者变少,但是为了减少bind()时的麻烦,可以统一设定就在0.0.0.0这个地址上监听。所有的信息都会到这个地址上,如果你需要将服务器上的所有IP中的80端口监听,再将80端口绑定就OK了,我就了解了这么多。

然后再看我们的客户端代码:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<netinet/in.h> int main(int argc,char *argv)
{
struct sockaddr_in serv_addr;
int conn_fd; //同样我们需要在客户端也建立套接字
conn_fd = socket(AF_INET,SOCK_STREAM,0); //初始化与服务器端匹配的信息
memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(4507);
inet_aton("192.168.20.144",&serv_addr.sin_addr); //用于向服务器端发送连接请求,服务器的IP地址和端口号由参数serv_addr指定
connect(conn_fd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr_in));
close(conn_fd);
}

客户端有点简单啊,但是可以登录,这样就可以基本实现我们的客户端和服务器之间连接了,下面我们进入我们的主题:是不是都忘了我们的主题是——“三次握手“。
在这个实例中,三次握手发生在客户端执行connect函数的时候。三次握手的过程下面的图片可以显示清楚,我再举个例子

第一次 client->server SYN=1,seq = x
第二次 server->client SYN=1,ACK = 1,seq = y,ack = x+1
第三次 client->server ACK=1,seq = x+1
SYN:同步序号,当SYN=1,ACK=0时,表明这是一个连接请求。
ACK:当ACK=1时,确认号字段即ack才有效。
seq:范围:[0,2^32 - 1],表示发送的第一个字节的编号。
ack:确认号,当ack = n,表示到n-1为止的所有字节都已经被收到。

另外我用tcpdump命令抓了个包,可以分析下,不对的地方指出

$ tcpdump port 4507


我的客户端IP为192.168.122.172,服务器的IP为192.168.20.128
第一次:Flag[S],表示这是一个请求连接,S是SYN字母的首字母,seq是将要发送的首字节的序列号,此时SYN = 1,ACK = 0。
第二次:收到SYN = 1的包,将ACK置为1,ack = 1588197944表示在此之前的字节我已经全部收到。
第三次:当再次收到SYN=1,ACK=1的包时,将ack = 1,表示确认连接。

“TCP:三次握手”分析——以一个简单的“服务器”和“客户端”为例的更多相关文章

  1. Wireshark抓包介绍和TCP三次握手分析

    wireshark介绍 wireshark的官方下载网站: http://www.wireshark.org/ wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示 ...

  2. TCP三次握手四次分手—简单详解

    关于TCP三次握手四次分手,之前看资料解释的都很笼统,很多地方都不是很明白,所以很难记,前几天看的一个博客豁然开朗,可惜现在找不到了.现在把之前的疑惑总结起来,方便一下大家. 疑问一,上图传递过程中出 ...

  3. 用C++写一个简单的服务器和客户端

    我们将创建一个服务器节点add_two_ints_server,它将会收到两个整数,并且返回它们的和.切换目录到之前建立的beginner_tutorials包下: cd ~/catkin_ws/sr ...

  4. 抓包工具-Wireshark(详细介绍与TCP三次握手数据分析)

    功能使用的详细介绍 wireshark(官方下载网站: http://www.wireshark.org/),是用来获取网络数据封包,可以截取各种网络封包,显示网络封包的详细信息,包括http,TCP ...

  5. Wireshark抓包TCP三次握手数据

    抓包工具 - Wireshark(详细介绍与TCP三次握手数据分析) 功能使用的详细介绍 wireshark(官方下载网站: http://www.wireshark.org/),是用来获取网络数据封 ...

  6. 这次一定让你记住 TCP 三次握手、四手挥手!

    TCP协议全称为:Transmission Control Protocol,是一种面向链接.保证数据传输安全.可靠的数据传输协议.为了确保数据的可靠传输,不仅需要对发出的每个字节进行编号确认,还需要 ...

  7. 详解TCP三次握手(建立TCP连接过程)

    在讲述TCP三次握手,即建立TCP连接的过程之前,需要先介绍一下TCP协议的包结构. 这里只对涉及到三次握手过程的字段做解释 (1) 序号(Sequence number) 我们通过 TCP 协议将数 ...

  8. 简单说说TCP三次握手、四次挥手机制

    1.什么是TCP TCP全称Transmission Control Protocol(传输控制协议),是一种面向连接的.可靠的.基于字节流的传输层通信协议.是为了在不可靠的互联网络上提供可靠的端到端 ...

  9. 用tcpdump分析tcp三次握手,四次挥手

    1.tcpdump 简介 tcpdump是一个对网络上的数据包进行截获的包分析工具,一般linux系统以命令的形式使用 2.tcp三次握手 建立一个tcp连接会发生下面三个过程: 1.服务器必须准备好 ...

随机推荐

  1. SonarScanner扫描Maven项目使用说明

    最近在学习使用sonar扫描代码,已经成功扫描python项目,而扫描java代码不成功. 在网上找到的扫描java项目文章,经过尝试之后也没有成功. 本人自己研究了sonar官方的使用说明文章,将其 ...

  2. javascript 定时器 timer setTimeout setInterval (js for循环如何等待几秒再循环)

    实现一个打点计时器,要求1.从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 12.返回的对象中需要包含一个 cance ...

  3. 一文让你彻底理解SELECT语句的执行逻辑

    正常情况下SELECT的书写顺序和执行顺序: 书写顺序: SELECT>FROM >WHERE>GROUP BY>HAVE>ORDER BY 执行顺序: FROM > ...

  4. Windows环境下实现WireShark抓取HTTPS

    https 加密传输,Wireshark 没有设置的情况下是没有办法抓到包的 https 的数据包. 设置系统环境变量(SSLKEYLOGFILE) WireShark 设置 SSL 选项 参考文章: ...

  5. python实现rtsp取流并截图

    import cv2 def get_img_from_camera_net(folder_path): cap = cv2.VideoCapture("rtsp://admin:admin ...

  6. python线程threading

    线程示例: import threading import time # 唱歌任务 def sing(): # 扩展: 获取当前线程 # print("sing当前执行的线程为:" ...

  7. 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 | 百篇博客分析OpenHarmony源码 | v71.01

    子曰:"我非生而知之者,好古,敏以求之者也." <论语>:述而篇 百篇博客系列篇.本篇为: v71.xx 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 ...

  8. 国庆出游神器:魔幻黑科技换天造物,让vlog秒变科幻大片!

    摘要:国庆旅游景点人太多,拍出来的照片全是人人人.车车车,该怎么办?不妨试试这个黑科技,让你的出游vlog秒变科幻大片. 本文分享自华为云社区<国庆出游神器,魔幻黑科技换天造物,让vlog秒变科 ...

  9. Unity——可复用背包工具

    Unity可复用背包工具 Demo展示 设计思路 游戏中有非常多的背包样式,比如玩家道具背包,商城,装备栏,技能栏等:每个形式的背包都单独写一份逻辑会非常繁琐,所以需要有一套好用的背包工具: 这些背包 ...

  10. 从零入门 Serverless | 函数计算如何粘合云服务,提供端到端解决方案

    作者 | 西流 阿里云技术专家 导读:阿里云 Serverless 产品函数计算可以作为粘合剂,串联其他云服务提供端到端解决方案,从而简化编程模型,快速实现最上层的业务目标. 传统单体应用的拆解 首先 ...