关于TCP下SOCKET的一些测试
=============================测试代码===========================
客户端:
#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的一些测试相关推荐
- JMeter测试TCP/IP Socket应用的性能
摘要 本文描述了如何利用JMeter来测试TCP/IP Socket应用的性能.文章先对Socket作了一点简单介绍,然后提供并解释了两个样例Socket应用,最后介绍如何利用JMeter来对它们进行 ...
- windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...
windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error 学习了:https ...
- Linux下Socket编程之TCP应用
现在,我们用前面所构建的socket类,重新设计<Linux下Socket编程之TCP Server端>中echo的服务器,然后设计客户端程序. echo服务器的工作原理很简单: 1.接收 ...
- 【Linux】一篇文章搞定 CPP模拟实现TCP协议下socket通信
CPP模拟实现TCP协议下socket通信 1. TCP 编程流程图 2. 数据收发阶段使用的API 2.1 send接口 2.2 recv接口 3. 两个队列 4. 总结TCP 编程双端流程 5. ...
- Linux下Socket编程
Linux下Socket编程 网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...
- LINUX下Socket编程 函数格式详解
你需要了解的一些系统调用: socket() bind() connect() listen() accept() send() recv() sendto() recvfrom() close() ...
- 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
转自即时通讯网:http://www.52im.net/ 本文原作者:"水晶虾饺",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说" ...
- 【Socket】Python UDP和TCP的socket实例
Socket UDP socket UDP Server端 UDP Client端 TCP socket TCP Server端 TCP Client端 总结 代码下载 Socket Socket又称 ...
- TCP/UDP,SOCKET,HTTP,FTP协议简析
(一)TCP/UDP,SOCKET,HTTP,FTP简析 TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层: 网络层:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议 传 ...
最新文章
- 小而美的个人博客——前端——types and archives
- LintCode 402: Continuous Subarray Sum
- android中拖动文字实现功能,Android:图片中叠加文字,支持拖动改变位置
- 搜索的php mysql代码生成器_四款强大的PHP代码生成器
- android学习笔记---50_样式与主题,给控件使用样式,给应用使用主题
- JavaScript Promise对象
- CPU里都有几十亿个晶体管,万一坏掉几个还能用吗?
- 【雷达通信】基于matlab联邦滤波算法惯性+GPS+地磁组合导航仿真【含Matlab源码 1276期】
- ASP.NET Page执行顺序如:OnPreInit()、OnInit()(转)
- 输入法半角和全角的快捷转换_华宇拼音输入法 一款完全免费的国产输入法_应用新闻-产经频道-中文科技资讯...
- 2020-12-24
- CDH踩坑记录之:熵不足
- 靶机渗透练习97-hacksudo:ProximaCentauri
- 【Lerna 基本使用】
- Xilinx 7系列FPGA收发器架构之接收器(RX)(十一)
- 程序设计大作业---超长正整数的减法
- 迪文串口屏的安装方法之卡扣结构带外壳智能屏
- TCP/IP 主要报文头格式
- 学了3,4年,终于明白了高斯白噪声的那些东西。
- 云服务器 虚拟主机 故障,云虚拟主机重启服务器
热门文章
- 资源权限操作-查询所有资源权限
- ES6新特性之map和reduce方法的使用
- Request_请求转发
- 关于idea右侧的maven project 如何调出来
- SpringBoot_web开发-【实验】-登陆拦截器
- Activemq实战
- 高性能Mysql--Schema与数据类型优化
- 【java】动态绑定机制
- signature=94f3cd0155e1d8c8ff09aa94177adccd,研擬顆粒流與連體數值耦合方法模擬山崩產生之震動訊號...
- python中类的定义方法_在Python中定义类变量的正确方法