=============================测试代码===========================

客户端:

#include<winsock2.h>                           //包含头文件
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"WS2_32.lib")             //显式连接套接字库int main()                                        //主函数开始
{WSADATA data;                              //定义WSADATA结构体对象WORD w=MAKEWORD(2,0);                      //定义版本号码::WSAStartup(w,&data);                      //初始化套接字库SOCKET s;                                  //定义连接套接字句柄char sztext[20]={0};s=::socket(AF_INET,SOCK_STREAM,0);         //创建TCP套接字sockaddr_in addr;                         //定义套接字地址结构addr.sin_family=AF_INET;                    //初始化地址结构addr.sin_port=htons(75);addr.sin_addr.S_un.S_addr=inet_addr("192.168.0.20");printf("客户端已经启动\r\n");               //输出提示信息int ret_con = ::connect(s,(sockaddr*)&addr,sizeof(addr));Sleep(100000);char t[200]="12345";int r = ::send(s,t,0,0);Sleep(1000);::closesocket(s);                   //关闭套接字句柄char buf[100]={0};int r2 = ::recv(s,buf,100,0);printf("%s",buf);::WSACleanup();                        //释放套接字库if(getchar())                       //如果有输入,则关闭程序{return 0;                      //正常结束程序}else{::Sleep(100);                 //程序睡眠}return 0;
}

服务器:

#include<winsock2.h>                       //包含头文件
#include<stdio.h>
#include<windows.h>
#pragma comment(lib,"WS2_32.lib")         //显式连接套接字库int main()                                    //主函数开始
{WSADATA data;                          //定义WSADATA结构体对象WORD w=MAKEWORD(2,0);                  //定义版本号码char sztext[]="你已经连接上";              //定义并初始化发送到客户端的字符数组::WSAStartup(w,&data);                   //初始化套接字库SOCKET s,s1;                           //定义连接套接字和数据收发套接字句柄s=::socket(AF_INET,SOCK_STREAM,0);      //创建TCP套接字sockaddr_in addr,addr2;                   //定义套接字地址结构int n=sizeof(addr2);                    //获取套接字地址结构大小addr.sin_family=AF_INET;              //初始化地址结构addr.sin_port=htons(75);addr.sin_addr.S_un.S_addr=INADDR_ANY;::bind(s,(sockaddr*)&addr,sizeof(addr));    //绑定套接字::listen(s,5);                               //监听套接字printf("服务器已经启动\r\n");             //输出提示信息while(true){s1=::accept(s,(sockaddr*)&addr2,&n);   //接受连接请求,正常情况下此函数是个阻塞函数,如果没有阻塞则是此函数运行失败if(s1!=NULL){printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr));//::send(s1,sztext,sizeof(sztext),0);  //向客户端发送字符数组}char buf[100]="";::recv(s1,buf,100,0);printf("%s",buf);Sleep(4*1000);char t[200]="12345";int r = ::send(s1,t,5,0);printf("\n%d\n",r);Sleep(10*1000);::closesocket(s1);Sleep(500*60*1000);::closesocket(s);                      //关闭套接字句柄::WSACleanup();                            //释放套接字库if(getchar())                           //如果有输入,则关闭程序{return 0;                          //正常结束程序}else{::Sleep(100);                     //应用睡眠0.1秒}}
}

======================================================================

测试环境:

本机:      WIN7     192.168.0.20

虚拟机:    WINXP   192.168.0.250

抓包工具:  Wireshark

测试内容:

1.客户端连接IP地址不存在或者端口没有开放

IP不存在时Wireshark抓不到数据包

使用下面的代码测试connect返回时间

int t1 = clock();

int ret_con = ::connect(s,(sockaddr*)&addr,sizeof(addr));

int t2 = clock() - t1;

测试结果是20秒

端口不存在时,可以抓到6个数据包

客户端尝试连接3次失败之后不再尝试连接

Connect函数返回时间是1秒

2.正常三次握手的抓包情况

成功抓到三次握手数据包。Connect返回时间为0

3.研究三次握手与accept函数有无关系

研究方法,服务器accept函数上面下断点,单步走,查看抓包情况

accept函数还没有调用已经抓到数据包,实验证明三次握手与accept函数无关

4.客户端简单发送一个数据包

服务器代码:(connect函数之后就一直sleep)

s1=::accept(s,(sockaddr*)&addr2,&n); //接受连接请求,正常情况下此函数是个阻塞函数,如果没有阻塞则是此函数运行失败

if(s1!=NULL)

{

printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr));

}

Sleep(1000 * 1000);

一共五条数据,前三条是3次握手,第四条是send发送”12345”的这条数据包,第5条是服务器响应数据包,表示自己已经收到数据了。测试过程中服务器并没来得及调用recv函数,说明TCP协议把数据先接收到了某个缓冲区,等待应用程序来读取。

5.客户端send发送数据为0的情况

服务器代码:

s1=::accept(s,(sockaddr*)&addr2,&n); //接受连接请求,正常情况下此函数是个阻塞函数,如果没有阻塞则是此函数运行失败

if(s1!=NULL)

{

printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr));

}

char buf[100]="";

::recv(s1,buf,100,0);

printf("接收到的数据为:%s",buf);

Sleep(400*1000);

客户端代码:

char t[200]="12345";

int r = ::send(s,t,0,0);

客户端方面没有抓到发送出去的数据包,只有握手数据包

服务器方面也没有收到数据包

调用closesocket函数之后客户端给服务发送了一个数据包,服务器发送了响应数据包

由于接收到客户端的closesocket函数,服务器的recv函数立即返回。

6.客户端send函数之后立即调用closesocket函数

直接运行:

可以看到:服务器方面没有响应客户端的send函数(发送相应的ACK数据包)而是直接响应了closesocket数据包。

但不运行:

数据包正常,分析原因应该是TCP的规定,接收到closesocket函数之后不再响应send的数据包

7.客户端连续调用send函数

服务器是否调用recv进行接受,客户端连续发送的数据会分两拨到达

服务器接受缓冲区够大的情况下

8.抓取四次握手释放连接数据包

服务器代码:

s1=::accept(s,(sockaddr*)&addr2,&n); //接受连接请求,正常情况下此函数是个阻塞函数,如果没有阻塞则是此函数运行失败

if(s1!=NULL)

{

printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr));

}

Sleep(2*1000);

::closesocket(s1);

客户端代码:

int ret_con = ::connect(s,(sockaddr*)&addr,sizeof(addr));

Sleep(1*1000);

::closesocket(s); //关闭套接字句柄

Sleep(100*1000);

要想抓到四次握手数据包必须一方先close函数,另一方紧接着close函数才可以

9.客户端closesocket之后服务器端一直sleep(不发送相应closesocket)

可以看到服务器端始终没有调用closesocket,120秒之后客户端采取另一个策略,发送RST数据包

10.测试TCP接收缓冲区

测试方法:客户端不停地发送数据,但是服务器始终不recv.

char buf[10] = "123456789";

for (int i=0;i<10000;i++)
{
int r = ::send(s,buf,10,0);
if (r != 10 || WSAGetLastError() != 0)
{
printf("---------------erro---------------\n");
}

}

printf("发送完成\n");

可以看到send函数阻塞了,不能发送数据了(底层TCP协议的控制)

关于TCP下SOCKET的一些测试相关推荐

  1. JMeter测试TCP/IP Socket应用的性能

    摘要 本文描述了如何利用JMeter来测试TCP/IP Socket应用的性能.文章先对Socket作了一点简单介绍,然后提供并解释了两个样例Socket应用,最后介绍如何利用JMeter来对它们进行 ...

  2. windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...

    windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error 学习了:https ...

  3. Linux下Socket编程之TCP应用

    现在,我们用前面所构建的socket类,重新设计<Linux下Socket编程之TCP Server端>中echo的服务器,然后设计客户端程序. echo服务器的工作原理很简单: 1.接收 ...

  4. 【Linux】一篇文章搞定 CPP模拟实现TCP协议下socket通信

    CPP模拟实现TCP协议下socket通信 1. TCP 编程流程图 2. 数据收发阶段使用的API 2.1 send接口 2.2 recv接口 3. 两个队列 4. 总结TCP 编程双端流程 5. ...

  5. Linux下Socket编程

    Linux下Socket编程    网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...

  6. LINUX下Socket编程 函数格式详解

    你需要了解的一些系统调用: socket() bind() connect() listen() accept() send() recv() sendto() recvfrom() close() ...

  7. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    转自即时通讯网:http://www.52im.net/ 本文原作者:"水晶虾饺",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说" ...

  8. 【Socket】Python UDP和TCP的socket实例

    Socket UDP socket UDP Server端 UDP Client端 TCP socket TCP Server端 TCP Client端 总结 代码下载 Socket Socket又称 ...

  9. TCP/UDP,SOCKET,HTTP,FTP协议简析

    (一)TCP/UDP,SOCKET,HTTP,FTP简析 TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议 传 ...

最新文章

  1. 小而美的个人博客——前端——types and archives
  2. LintCode 402: Continuous Subarray Sum
  3. android中拖动文字实现功能,Android:图片中叠加文字,支持拖动改变位置
  4. 搜索的php mysql代码生成器_四款强大的PHP代码生成器
  5. android学习笔记---50_样式与主题,给控件使用样式,给应用使用主题
  6. JavaScript Promise对象
  7. CPU里都有几十亿个晶体管,万一坏掉几个还能用吗?
  8. 【雷达通信】基于matlab联邦滤波算法惯性+GPS+地磁组合导航仿真【含Matlab源码 1276期】
  9. ASP.NET Page执行顺序如:OnPreInit()、OnInit()(转)
  10. 输入法半角和全角的快捷转换_华宇拼音输入法 一款完全免费的国产输入法_应用新闻-产经频道-中文科技资讯...
  11. 2020-12-24
  12. CDH踩坑记录之:熵不足
  13. 靶机渗透练习97-hacksudo:ProximaCentauri
  14. 【Lerna 基本使用】
  15. Xilinx 7系列FPGA收发器架构之接收器(RX)(十一)
  16. 程序设计大作业---超长正整数的减法
  17. 迪文串口屏的安装方法之卡扣结构带外壳智能屏
  18. TCP/IP 主要报文头格式
  19. 学了3,4年,终于明白了高斯白噪声的那些东西。
  20. 云服务器 虚拟主机 故障,云虚拟主机重启服务器

热门文章

  1. 资源权限操作-查询所有资源权限
  2. ES6新特性之map和reduce方法的使用
  3. Request_请求转发
  4. 关于idea右侧的maven project 如何调出来
  5. SpringBoot_web开发-【实验】-登陆拦截器
  6. Activemq实战
  7. 高性能Mysql--Schema与数据类型优化
  8. 【java】动态绑定机制
  9. signature=94f3cd0155e1d8c8ff09aa94177adccd,研擬顆粒流與連體數值耦合方法模擬山崩產生之震動訊號...
  10. python中类的定义方法_在Python中定义类变量的正确方法