Socket TCP Ping使用小结

您所在的位置:网站首页 真连接延迟和ping的区别 Socket TCP Ping使用小结

Socket TCP Ping使用小结

2024-07-17 13:46| 来源: 网络整理| 查看: 265

TCP Ping 检测网络延迟 原理是,先在客户端和服务端建立一个tcp连接,然后发出一个检测包,测量响应时间 为了能够实现对网络延迟的监测,我们可以使用TCP协议进行ping。它和ping的普通区别,是在测量前要建立一个tcp连接。 关于socket的概念

这里附上一个链接:Socket连接与HTTP连接 主要介绍socket与Http连接的特点与区别,重点是要看看利用Socket建立网络连接的步骤

下面上代码 创建 socket /**参数 domain:协议域,AF_INET->IPV4 type:Socket 类型,SOCK_STREAM(TCP)/SOCK_DGRAM(报文 UDP) protocol: IPPROTO_TCP,如果传入0,会自动根据第个参数,选 择合适的协议 返回值 socket > 0 就成功 */ int clientSocket = socket(AF_INET, SOCK_STREAM, 0); 连接到服务器 /**参数 1> 客户端socket 2> 服务器地址结构体指针 3> 结构体数据长度 返回值 0 成功/其他 错误代号 */ struct sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; // 端口 serverAddr.sin_port = htons(80); // 地址 inet_addr 函数,可以将 ip 地址转换成一个数字(你想连接的服务器ip) serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); int connResult = connect(clientSocket, (const struct sockaddr *)&serverAddr, sizeof(serverAddr)); if (connResult == 0) { NSLog(@"连接成功!"); } else { NSLog(@"失败 %d", connResult); return; } ``` * 发送数据给服务器 ``` /** 参数 1> 客户端socket 2> 发送内容地址 3> 发送内容长度 4> 发送方式标志,一般为0 返回值 如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR */ self.begintime = [self timeNowGetter]; NSLog(@"begintime:%f",[self timeNowGetter]); NSString *sendMsg = @"hello"; ssize_t sendLen = send(clientSocket, sendMsg.UTF8String, strlen(sendMsg.UTF8String), 0); NSLog(@"发送了 %ld 个字节", sendLen); ``` * 从服务器接收数据 ``` /** 参数 1> socket 2> 接收数据的缓冲区地址,需要提前准备 3> 缓冲区长度 4> 标记,0,阻塞式 返回值 如果成功,则返回接收到的字节数 */ uint8_t buffer[1024]; // 要把空间准备出来 ssize_t recvLen = recv(clientSocket, buffer, sizeof(buffer), 0); NSLog(@"接收了 %ld 个字节 ", recvLen); NSLog(@"时间差-->endTime:%f",([self timeNowGetter] - self.begintime)*1000); // 获取服务器返回的数据,从缓冲区中读取 recvLen 个字节! NSData *data = [NSData dataWithBytes:buffer length:recvLen]; // 转换成字符串 NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"====%@", str); ``` * 关闭 ``` /** 长连接:连上就一直聊!通常用于 QQ,即时通讯,效率高! 短连接:通讯一次,马上断开,下一次再次建立连接,效率低 */ close(clientSocket); 注意点(明明是长连接怎么一次发送后就断开了??)

通常情况下我们要是做即时通讯类的其端口号一般要大于1024

以上代码很有可能一次发送数据后,连接断开,再次发送数据就收不到回复是因为服务器端对我们发送的data做了判断,如果我们发送的数据不遵守HTTP协议,服务器端会断开连接

为了避免服务器断开,客户端发送数据时要遵守HTTP协议附上连接可以查看:HTTP 请求消息的结构 大体内容如下:

REST 服务是通过标准 HTTP 请求来访问的,一个完整的 HTTP 请求由三个部分组成:请求行(Request Line)、消息头(Message Headers)和消息体(Entity Body),消息头与消息体之间通过空行(没有内容的行,即只有回车符和换行符)来分隔。 请求行(Request Line)

请求行由三个标记组成:

请求方法、请求 URI 和 HTTP 版本,它们用空格分隔。 例如:GET /news.asp HTTP/1.1

消息头(Message Headers)

由域名/值对组成 每行一对,域名和值之间用紧跟的英文冒号(“:”),单空格(SP)分开。 消息头通知服务器有关于客户端的功能和标识。 如 Host: http://demo.com:80 表示请求的资源所在的主机和端口号,在 HTTP/1.1 协议中,Host 消息头是必选的。 还可以有其他一些如 Accept-Charset、Accept-Encoding、Authorization 等等,详见 RFC1945,RFC2616。

消息体(Entity Body)

HTTP 消息的消息体(如果存在),用于携带与请求相关联的数据,例如可以存一些请求需要的参数等。 由消息头中的 Content-Length 或 Transfer-Encoding 来指示。 消息头里的 Content-Type 说明了数据的传输类型。 一个完整的带消息体的 HTTP 一个完整的带消息体的 HTTP 请求示例如下: POST /news.asp HTTP/1.1 Host: demo.com:80 * 如果没有news.asp,直接 POST / HTTP/1.1 * demo.com 换成ip也可以 注意点(connection/send/recv timeOut的设置)

这里附上一个链接:setsockopt 设置socket 详细用法(超时、非阻塞等) 下面将主要代码摘出来

发送/接受 延迟设置 struct timeval timeout = {3,0}; //设置发送超时 setsockopt(socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval)); //设置接收超时 setsockopt(socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval));

这里还要说一下struct timeval timeout = {3,0};

_STRUCT_TIMEVAL { __darwin_time_t tv_sec; /* seconds */ __darwin_suseconds_t tv_usec; /* and microseconds */ }; * tv_sec :单位为秒(s)延 * tv_usec :单位为秒(ns)1000000ns = 1s

意思就是说延迟时间为3s。

connection 延迟设置 Linux内核源码中connect的超时参数和SO_SNDTIMO操作的参数一致。 因此,在linux平台下,可以通过connect之前设置SO_SNDTIMO来达到控制连接超时的目的 关于 网络延迟检测:

计算网络延迟就可以在发送数据时获取下当前时间beginTime,收到回复时获取下当前时间endTime ,duration = endTime - begin 即可。

期待:我整理好代码会在gitHub上上传相关代码,有需要的小伙伴可以直接clone 拖走…求Start~~


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3