文章目录

  • UNIX_NET
    • 获取服务器时间
      • connect函数
      • 获取时间客户端程序实现
      • 获取时间服务器实现
    • 小技巧
      • 宏定义的使用&&变参函数的宏定义实现
    • 源码地址

UNIX_NET

获取服务器时间

connect函数

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);DESCRIPTIONThe  connect()  system  call connects the socket referred to by the file descriptor sockfd to the address specified by addr.  The addrlen argument specifies the size of addr.  The format  of  the address  in  addr is determined by the address space of the socket sockfd; see socket(2) for fur‐ther details.If the socket sockfd is of type SOCK_DGRAM, then addr is the address to which datagrams are  sent by  default,  and  the  only address from which datagrams are received.  If the socket is of type SOCK_STREAM or SOCK_SEQPACKET, this call attempts to make a connection  to  the  socket  that  is bound to the address specified by addr.Generally, connection-based protocol sockets may successfully connect() only once; connectionless protocol sockets may use connect() multiple times to change  their  association.   Connectionless sockets  may  dissolve  the  association by connecting to an address with the sa_family member of sockaddr set to AF_UNSPEC (supported on Linux since kernel 2.2).RETURN VALUEIf the connection or binding succeeds, zero is returned.  On error, -1 is returned, and errno  is set appropriately.

获取时间客户端程序实现

#include "unix_net_public.h"
#include <stdio.h>
#include <strings.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>#define MAXLINE 4096int main(int argc, char *argv[])
{int sockfd, n;char recvline[MAXLINE + 1];struct sockaddr_in servaddr;//< 没有指定IP进行报错处理if (argc != 2){UNIX_NET_DEBUG("usage: <IPaddress>\n");exit(1);}//< AF_INET 通常代表地址族协议  PF_INET 通产代表网络协议族协议if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <  0){perror("socket error!\n");}//<  将地址结构体中的数据进行清空处理bzero(&servaddr, sizeof(servaddr));//< 构造结构体servaddr.sin_family = AF_INET;servaddr.sin_port = htons(8560); // 没有找到时间服务器使用ssh端口连接自己的电脑测试连 connect函数的实现//< 将点十进制地址转换为网络地址if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){perror("inet_pton error  \n");}//< 使用connect创建连接UNIX_NET_DEBUG("connect start\n");if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){perror("connect error\n");}UNIX_NET_DEBUG("connect is end !\n");//< 接受服务器的回复数据while((n = read(sockfd, recvline, MAXLINE)) > 0){recvline[n] = 0;if(fputs(recvline, stdout) == EOF){perror("fputs error\n");}}if (n < 0){perror("error exit()");}return 0;
}

支持IPv6的实现

#include "unix_net_public.h"int
main(int argc, char **argv)
{int                    sockfd, n;struct sockaddr_in6   servaddr;char               recvline[MAXLINE + 1];if (argc != 2)UNIX_NET_DEBUG("usage: a.out <IPaddress>");//< 使用网际协议  字节流的形式创建 socket句柄if ( (sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0)UNIX_NET_DEBUG("socket error");bzero(&servaddr, sizeof(servaddr));servaddr.sin6_family = AF_INET6;servaddr.sin6_port   = htons(8560); /* daytime server *///< 将IP地址转换为网络地址if (inet_pton(AF_INET6, argv[1], &servaddr.sin6_addr) <= 0)UNIX_NET_DEBUG("inet_pton error for %s", argv[1]);if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)UNIX_NET_DEBUG("connect error");//< 使用阻塞的凡是进行read函数读取数据while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0; /* null terminate */if (fputs(recvline, stdout) == EOF)UNIX_NET_DEBUG("fputs error");}if (n < 0)UNIX_NET_DEBUG("read error");return 0;
}

获取时间服务器实现

#include "unix_net_public.h"int
main(int argc, char **argv)
{int                    listenfd, connfd;struct sockaddr_in servaddr;char               buff[MAXLINE];time_t                ticks;//< 创建套接字,文件描述符listenfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family      = AF_INET;//< 监听所有的笛子, Address to accept any incoming messages. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//< 尽量使用大于8000的端口,小端口在linux上使用可能会报错不让使用servaddr.sin_port        = htons(8560);   /* daytime server *///< 绑定套接字bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));listen(listenfd, LISTENQ);for ( ; ; ) {connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);ticks = time(NULL);snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));write(connfd, buff, strlen(buff));close(connfd);}
}

以上代码全部在UBUNTU 16.04上测试通过,可以去github上下载对应的源码,直接编译

测试

$ ./putdaytimesrv &
[1] 2952
$ ./getdaytimetcpclient 127.0.0.1
[getdaytimetcpclient.c], lien  = [47]connect start
[getdaytimetcpclient.c], lien  = [52]connect is end !
Sun Jul 14 14:57:22 2019

数据发送的过程刚好是三次握手,四次挥手加上一次(PSH,ACK)

抓包分析:
启动wireshark 抓取lo网卡的网络数据:
然后执行上述操作,对操作过程中产生的网络数据进行抓包
整个过程经历了三次握手和四次挥手,途中总共有7帧数据,前三帧是三次握手,后四帧是四次挥手,中间的那一次是PSH, ACK帧,是数据的发送帧



小技巧

宏定义的使用&&变参函数的宏定义实现

#define UNIX_NET_DEBUG(...) do { \printf("[%s], lien  = [%d]", __FILE__, __LINE__); \printf(__VA_ARGS__); \}while(0)

源码地址

github

关注公众号

SOCKET编程-时间服务器和客户端的实现相关推荐

  1. 服务器没有响应客户端,socket编程某些服务器对某些客户端没有响应的问题!!...

    socket编程某些服务器对某些客户端没有响应的问题!! 我是这么用的t=serversocket(inetaddress,2); while(true){ t=y.accept(); out=new ...

  2. 【Linux】socket网络编程之服务器与客户端的数据交互

    [Linux]socket网络编程之服务器与客户端的数据交互 前言参考 argc !=2是什么意思 inet pton函数 对stdin,stdout 和STDOUT_FILENO,STDIN_FIL ...

  3. Netty -Netty心跳检测机制案例,Netty通过WebSocket编程实现服务器和客户端长链接

    Netty心跳检测机制案例 案例要求 编写一个Netty心跳检测机制案例,当服务器超过3秒没有读时,就提示读空闲 当服务器超过5秒没有写操作时,提示写空闲 服务器超过7秒没有读或者写操作时,就提示读写 ...

  4. Netty 通过 WebSocket 编程实现服务器和客户端全双工长连接<2021SC@SDUSC>

    2021SC@SDUSC Netty 通过 WebSocket 编程实现服务器和客户端全双工长连接 实例要求: Http 协议是无状态的, 浏览器和服务器间的请求响应一次,下一次会重新创建连接. 要求 ...

  5. python应用系列教程——python使用socket创建tcp服务器和客户端

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python使用socket创建tcp服务器和客户端. 服务器端为一个时间戳服务器,在接收到客户端发来的数据后,自动回复. 客户端,等待用户输 ...

  6. Linux下网络socket编程——实现服务器(select)与多个客户端通信

    一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...

  7. Socket编程获取服务器时间

    客户端向服务器端发送请求,服务器收到请求做相应的处理,将处理结果传回客户端.下面采用TCP协议实现服务器和客户端之间的连接. 1.      客户端 约定双方的传输协议(UDP或者TCP),根据传输协 ...

  8. Java Socket编程 文件传输(客户端从服务器下载一个文件)

    服务器(Server) [java] view plaincopy  package com.socket.sample;      import java.io.BufferedInputStrea ...

  9. java基础 day12-FileInputStream类,文件的复制,缓冲流,Propertes文件,xml文件读写,网络socket编程(构建TCP客户端),内部类

    FileInputStream类的其他常用方法() /**在project下新建temp文件,内容为abcdef*FileInputStream类的其他常用方法:* int available():返 ...

最新文章

  1. seaborn使用displot函数实现多面板直方图(Multi-panel)可视化:使用set_title函数自定义设置多面板直方图标题(Multi-panel histograms’ title)
  2. 简单了解音视频传输协议SDP、RTP、RTMP、SIP等
  3. SET_TABLE_FOR_FIRST_DISPLAY 参数 I_SAVE
  4. 深夜更新鸿蒙OS生态服务,华为频频深夜更新,HMS生态服务范围不断扩大,离替代谷歌不远了?...
  5. 火币网的macd怎么算的_黄金投资中MACD的计算方式
  6. 校验用户画像的准确性
  7. 什么是PCM综合语音复用设备?
  8. 法斗几个月长鼻筋_路医生说丨脚底板早起一下地特别疼?得了足底筋膜炎,该怎么办?...
  9. Jackson快速入门
  10. Socket编程实践(13) --UNIX域协议
  11. Apache发布NetBeans 10.0,增强对JDK 11的支持
  12. .net core websocket
  13. 计算机网络与应用第三次笔记
  14. Simple QQLogin 1.3(QQ2008 或更早版本)
  15. stm32开发3D打印机(一)——介绍(已完成)
  16. 距离拿下千亿市场,AR眼镜还缺什么?
  17. 鸿蒙芯片是华为公司靠几年造出来的,难度不输芯片制造,华为高管实话实说,造出操作系统只是开始...
  18. 用huggingface.transformers在文本分类任务(单任务和多任务场景下)上微调预训练模型
  19. 在iPhone应用里直接打开app store 评论页面的方法
  20. 设计一个形状类(接口)Shape,方法:求周长和求面积形状类(接口)的子类(实现类): Rect(矩形) Circle(圆形)Rect类的子类: Square(正方形)不同的子类会有不同的计算周长和面

热门文章

  1. hdu 5631 Rikka with Graph(无向图的割边)
  2. nyoj1228矩形判断
  3. NYOJ 108 士兵杀敌(一)
  4. NYOJ 496 巡回赛 拓扑排序
  5. 七.Hystrix Timeout机制
  6. SQLServer—端口概念
  7. nginx反向代理配置及优化
  8. python之初体验(一)
  9. 平均值,方差计算(sss)
  10. 深入ASP.NET数据绑定(上)