当前位置: 首页 > news >正文

常州市建设工程质监站网站电商app开发公司

常州市建设工程质监站网站,电商app开发公司,如何建立一个网站平台网站,小型网站设计及建设论文范本目录 预备知识 socket通信的本质 认识TCP协议和UDP协议 网络字节序 socket编程流程 socket编程时常见的函数 服务端绑定 整数IP和字符串IP 客户端套接字的创建和绑定 预备知识 理解源IP和目的IP 源IP指的是发送数据包的主机的IP地址#xff0c;目的IP指的是接收数据包…目录 预备知识 socket通信的本质 认识TCP协议和UDP协议 网络字节序 socket编程流程 socket编程时常见的函数 服务端绑定 整数IP和字符串IP 客户端套接字的创建和绑定 预备知识 理解源IP和目的IP 源IP指的是发送数据包的主机的IP地址目的IP指的是接收数据包的主机的IP地址。在网络通信中当一台主机需要向另一台主机发送数据包时它需要将数据包的目的IP地址设置为接收主机的IP地址同时在数据包的头部中加入源IP地址以便接收主机能够知道数据包来自哪个主机。 理解源MAC地址和目的MAC地址 源MAC地址和目的MAC地址是数据链路层中的两个重要概念MAC地址是每个网卡独有的物理地址用于在局域网中标识设备。 源MAC地址是指发送数据包的主机的网卡的MAC地址目的MAC地址是指接收数据包的主机的网卡的MAC地址。在数据包传输过程中数据包的源MAC地址和目的MAC地址会随着数据包一起传输并被中间的路由器或交换机使用来判断数据包的转发。 当数据包从源主机发送时它首先需要找到目的主机所在的网卡这时候就需要目的MAC地址。发送主机会将目的MAC地址填入数据包中以便路由器或交换机能够将数据包准确地发送给目的主机。而源MAC地址则用于标识数据包的来源这样目的主机就能够知道数据包是从哪个主机发送过来的 理解源端口号和目的端口号 在TCP/IP协议中源端口号和目的端口号是定义在传输层的概念用于在不同主机之间的通信中唯一标识一个虚拟连接。源端口号和目的端口号组成了一个socket可以理解为一个网络应用程序的地址。 源端口号是发送方的端口号目的端口号是接收方的端口号。在发送数据时网络应用程序会将数据发送给目标主机的特定端口号而接收方则会通过监听特定端口号来接收发送方传来的数据。 端口号的范围是0~65535其中0~1023是系统端口号已经被分配给一些知名的服务或应用程序比如80号端口是HTTP服务默认端口、 21号端口是FTP服务默认端口、25号端口是SMTP服务默认端口。而1024~65535是动态端口号可以由应用程序自行分配使用。 通过源端口号和目的端口号TCP/IP协议可以建立并维护一条虚拟连接保证数据包的可靠传输并可以区分不同的应用程序之间的通信。 socket通信的本质 Socket通信的本质是建立在TCP/IP协议之上的一种应用层协议它用于在网络上实现进程之间的通信。在Socket通信中进程可以作为客户端或服务器端通过IP地址和端口号建立连接并进行数据传输。 在建立Socket连接时客户端会向特定IP地址和端口号发送连接请求服务器端会接受连接请求并建立连接。一旦连接建立成功客户端和服务器端就可以通过Socket实例进行数据的收发。 Socket通信的本质是通过TCP/IP协议在网络上传输数据确保数据的可靠性和稳定性。TCP协议提供可靠的数据传输和流量控制IP协议提供数据包的路由和分发。通过Socket通信可以建立一对一、一对多、多对多的通信方式实现进程之间的高效通信广泛应用于互联网、局域网和各种分布式系统中。 总结通过IP地址和MAC地址可以实现数据有一台主机传输到另一台主机了但在实际生活中我们希望的是能将数据传输到指定的应用中在机器上称进程例如我们在自己主机上的京东APP上点赞一个店家时我们希望这个数据会传输到其它主机上的京东APP上而不是淘宝APP或其它APP。这时就需要使用端口号来标识特定的进程APP。 在不同的两台主机上可能会同时存在多个正在进行跨网络通信的进程当数据到达目的主机时就需要通过端口号找到该主机上对应的通信进程然后将数据交给该进程进行处理。而该主机也需要记住发送端的信息当数据处理完后返还处理结果。 端口号的理解 端口号(port)是传输层协议的内容 端口号是一个2字节16位的整数; 端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理; IP地址 端口号能够标识网络上的某一台主机的某一个进程; 一个端口号只能被一个进程占用。 理解 端口号 和 进程ID 到这里有人会问当数据到达目的主机时为何不以进程PID为根据将数据发送给目的进程端口号prot)的作用和进程ID具有同样的功能都是唯一标识一台主机上的某一个进程。为何还要创建出端口号 首先进程ID是用于唯一标识系统内所有进程的属于系统级概念端口号用于唯一标识系统内要进行跨网络通信的进程属于网络概念。并不是所有的进程都需要进行跨网络通信。 当数据到达目的主机时如何找到要接收数据的端口号 底层采用哈希表方式建立端口号和进程IPD或PCB之间的映射当底层拿到端口号时通过算法找到对应的进程。 认识TCP协议和UDP协议 TCP协议 TCP协议Transmission Control Protocol传输控制协议是一种可靠的、面向连接的协议。它主要用于在计算机网络上提供可靠的数据传输服务。 TCP协议是一种面向字节流的协议它通过将数据分成一系列的数据包进行传输从而保证了数据的可靠性。在TCP连接建立后通信双方将通过三次握手建立连接。数据传输过程中TCP协议会对每一个数据包进行确认和校验确保数据的完整性和正确性。当接收方接收到一个数据包时会向发送方发送一个确认消息确保发送方已经正确地发送了该数据包。如果发送方在一定时间内没有收到确认消息它会重新发送相同的数据包以确保数据的可靠传输。 总结 传输层协议 有连接 可靠传输 面向字节流 UDP协议 UDP协议User Datagram Protocol用户数据报协议是一种简单的、无连接的网络传输协议。UDP协议的特点是速度快但可靠性比较低。 UDP协议是一种面向数据报的协议它将数据分割成一个个独立的数据包进行传输这些数据包被称为用户数据报UDP Datagram。在传输数据的过程中UDP协议不会进行数据的确认和校验也不会保证数据的顺序性。因此UDP协议比TCP协议要快很多但会存在数据丢失的风险。 总结 传输层协议 无连接 不可靠传输 面向数据报 网络字节序 网络字节序也叫大端字节序是一种字节序byte order规范它规定了数据在网络传输时的排序方式。 计算机数据存储模式 大端模式数据的高字节存储在低地址低字节存储在高地址。 小端模式数据的高字节存储在高地址低字节存储在低地址。 在网络传输中不同计算机上的处理器可能采用不同的字节序为了保证数据在网络中传输时的正确性就需要使用统一的字节序即网络字节序。在网络字节序中整数类型的数据的高字节存储在低地址低字节存储在高地址与大端字节序相同。而在小端字节序中整数类型的数据的高字节存储在高地址低字节存储在低地址。因此在网络传输中数据需要转换为网络字节序才能确保不同计算机之间的数据传输的正确性。 网络字节序是一种字节序规范它规定了数据在网络传输时的排序方式能够保证不同计算机之间的数据传输的正确性。 socket编程流程 sockaddr结构 套接字属于进程间通信中的一种它支持本地通信和网络通信。在使用套接字进行跨网络通信是我们需要指明IP地址和端口号而使用于本地通信则不需要因此套接字提供了sockaddr_in结构体和sockaddr_un结构体其中sockaddr_in结构体用于跨网络通信而sockaddr_un结构体用于本地通信网络让套接字的本地通信和跨网络通信都能使用一套相同的接口系统还提供了sockaddr结构体。这三个结构体的头部的16个比特位都是一样的这个字段叫协议家族。 所以我们在传参是就不用传入sockaddr_in或sockaddr_un这样的结构体而使用统一的sockaddr,我们通过设置协议家族参数来表明我们要进行本地通信还是网络通信这样套接字的本地通信和网络通信就得到了统一。 注意在编写程序时还是使用相应得结构体如要进行网络通信时定义时仍使用sockaddr_in,但在传参时强转为sockaddr*。 socket编程时常见的函数 socket( ) socket( )是一个系统调用用于在应用程序中创建一个新的套接字socket。 该函数的原型如下 int socket(int domain, int type, int protocol); 函数参数说明 domain套接字通信的协议族,相当于struct sockaddr结构体的前16位如果使用于本地通信就设置为AF_UNIX如果使用于网络通信就设置AF_INETIPv4协议和AF_INET6IPv6协议等。type套接字的类型常见的有SOCK_STREAM面向连接的TCP协议和SOCK_DGRAM无连接的UDP协议等。protocol指定协议通常为0表示使用默认协议。 函数返回值 成功返回一个socket的文件描述符可以用于后续网络通信中。失败返回-1并设置errno全局变量表示具体错误原因。 当我们在程序中执行了socket函数时底层会进行以下几个步骤 内核创建一个新的socket对象并为它分配唯一的文件描述符。 内核为此socket分配相关的资源包括缓冲区、状态信息等。 内核为此socket分配本地端口号如果是TCP协议的话并对本地端口进行绑定bind操作使得其它进程可以通过这个端口号来与此socket进行通信。 内核返回新socket对象的文件描述符程序可以通过这个文件描述符来访问此socket。 当进程调用socket函数时实际就相当于打开了一个“网络文件”这时进程就要对这个网络文件进行管理就要为这个网络文件分配文件描述符这个文件描述符会作为socket函数的返回值返回用户与普通的磁盘文件不同的是磁盘文件是将数据刷新到磁盘上就完成了数据的操作而网络文件则是将文件缓冲区的数据将会刷新到网卡里而卡是负责数据发送的最终会将数据发送到网络中。 创建套接字 进行创建套接字时要根据使用场景而填入相应的参数这里我们使用UDP进行网络通信所以协议族填AF_INET,SOCK_DGRAM第三个参数填0为默认。 class udpserver {public: bool InitServer() {//创建套接字_sockfdsocket(AF_INET,SOCK_DGRAM,0);//AF_INET//表示要进行网络通信SOCK_DGRAM UDP协议if(_sockfd0){//表示创建套接字失败std::cout socket error;return false;}std::cout socket create success,socfd:_sockfd std::endl;return true;} ~udpserver() {if(_sockfd0){close(_sockfd);//关闭文件描述符} } private: int _sockfd;//网络文件描述符};#includeserver.hpp int main() {udpserver* sernew udpserver();ser-InitServer();return 0; } 运行结果  服务端绑定 套接字创建好后就相当于打开了一个文件这个文件和其他文件并没有什么不同操作系统并不知道要将文件的内容写到磁盘还网卡所以我们需要将这个文件与一个本地地址进行绑( 通常指IP地址和端口号) , 这就不得不介绍bind函数。 bind函数是一个系统调用它在应用程序的套接字socket和本地地址IP地址和端口号之间建立一个关联关系使得其他应用程序可以通过该本地地址与该套接字进行通信。bind函数的主要作用是将一个特定的套接字绑定到一个特定的本地地址上使得该套接字在网络上唯一地标识一个通信节点从而实现网络通信。bind函数的函数原型如下 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);其中sockfd是由socket函数返回的套接字描述符addr是一个指向本地地址结构体的指针addrlen是该结构体的长度。bind函数的调用方法如下 struct sockaddr_in addr; int sockfd socket(AF_INET, SOCK_STREAM, 0); // 创建一个TCP套接字 memset(addr, 0, sizeof(addr)); // 清空地址结构体 addr.sin_family AF_INET; // 设置地址族为IPv4 addr.sin_addr.s_addr htonl(INADDR_ANY); // 设置本地地址为任意IP地址 addr.sin_port htons(8080); // 设置本地端口号为8080 if (bind(sockfd, (struct sockaddr *)addr, sizeof(addr)) 0) { // 绑定套接字和本地地址perror(bind error);exit(EXIT_FAILURE); }在上面的例子中我们首先通过socket函数创建了一个TCP套接字然后创建了一个本地地址结构体addr该结构体包含了本地IP地址和端口号等信息然后将该结构体和套接字描述符作为参数传入bind函数中调用bind函数将套接字和本地地址绑定起来。在绑定成功后应用程序就可以通过该本地地址来访问该套接字实现网络通信的功能。 #pragma once#include iostream #include cerrno #include cstring #include cstdlib #include functional #include strings.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include pthread.h #includeunistd.h #include unordered_map using namespace std;class udpserver {public: udpserver(std::string ip,int port):_sockfd(-1),_port(port),_ip(ip) {} bool InitServer() {//创建套接字_sockfdsocket(AF_INET,SOCK_DGRAM,0);//AF_INET//表示要进行网络通信SOCK_DGRAM UDP协议if(_sockfd0){//表示创建套接字失败std::cout socket error;return false;}std::cout socket create success,socfd:_sockfd std::endl;struct sockaddr_in local;memset(local,\0,sizeof(local));//清空结构体local.sin_familyAF_INET;local.sin_porthtons(_port);local.sin_addr.s_addrinet_addr(_ip.c_str());//绑定if(bind(_sockfd,(struct sockaddr*)local,sizeof(sockaddr))0){std::coutbind errorstd::endl;return false;}std::coutbind successstd::endl;return true;}~udpserver() {if(_sockfd0){close(_sockfd);//关闭文件描述符} } private: int _sockfd;//网络文件描述符 int _port;//端口号 std::string _ip;//IP地址};#includeserver.hpp int main(int argc,char*argv[]) {if(argc!2){std:coutusage:argv[0] portstd::endl;return 1;}std::string ip127.0.0.1;int portatoi(argv[1]);udpserver* sernew udpserver(ip,port);ser-InitServer();return 0; } 整数IP和字符串IP IP地址是Internet Protocol的缩写是一个32位二进制数通常表示为四个8位二进制数即四个数字每个数字范围在0到255之间用点分十进制形式表示。例如192.168.1.1 IP地址的表示形式有两种 整数IP将点分十进制形式表示的IP地址转换为一个32位整数例如192.168.1.1可以转换为十进制数3232235777。 字符串IP即点分十进制形式表示的IP地址例如192.168.1.1。 整数IP转为字符串IP 将整数IP转换为字符串IP的主要原因是方便人们阅读和理解IP地址。字符串IP的形式更符合人们的阅读习惯同时也更容易记忆。在实际应用中比如在配置网络设备和编写网络应用程序时我们通常使用字符串IP来表示IP地址因为这更符合人们的直觉和需要。 inet_ntoa()函数是一个用于将32位无符号整数表示的IP地址转换为点分十进制字符串表示的网络函数。它的头文件为arpa/inet.h使用时需要包含该头文件。 该函数的原型如下 char *inet_ntoa(struct in_addr in);参数in是一个struct in_addr类型的结构体表示待转换的32位无符号整数表示的IP地址。函数返回值是转换后的点分十进制字符串表示的IP地址如果转换失败则返回NULL。 例如以下代码将32位无符号整数表示的IP地址192.168.0.1转换为点分十进制字符串并打印出转换后的结果 inet_ntoa()函数是一个用于将32位无符号整数表示的IP地址转换为点分十进制字符串表示的网络函数。它的头文件为arpa/inet.h使用时需要包含该头文件。 该函数的原型如下 char *inet_ntoa(struct in_addr in);参数in是一个struct in_addr类型的结构体表示待转换的32位无符号整数表示的IP地址。 函数返回值是转换后的点分十进制字符串表示的IP地址如果转换失败则返回NULL。 例如以下代码将32位无符号整数表示的IP地址192.168.0.1转换为点分十进制字符串并打印出转换后的结果 #include stdio.h #include arpa/inet.hint main() {in_addr_t ip_int 3232235521; // 192.168.0.1的32位无符号整数表示struct in_addr in;in.s_addr ip_int;char* ip_str inet_ntoa(in);if (ip_str NULL) {printf(IP address conversion error!\n);return -1;} else {printf(IP address in string format: %s\n, ip_str);return 0;} }需要注意的是由于inet_ntoa()函数返回的是指向静态缓冲区的指针因此每次调用该函数时返回的字符串都会被覆盖。如果需要保存转换后的IP地址字符串可以使用strdup()函数对其进行复制。 recvfrom()函数是一个用于在UDP协议中接收数据的网络函数。它的头文件为sys/socket.h使用时需要包含该头文件。 该函数的原型如下 ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);参数说明 参数sockfd为已经创建好的socket文件描述符用于接收数据 参数buf为接收数据的缓冲区参数len为缓冲区的长度即最多接收的字节数 参数flags一般为0表示没有特殊要求 参数src_addr为指向存放发送者IP地址和端口号的sockaddr结构体指针 参数addrlen为指向sockaddr结构体长度的指针接收到的发送者地址长度会写入其中。 返回值函数返回值为接收到的字节数如果出错则返回-1。 注意udp是不面向连接的所以在使用udp协议进行通信时我们在获取数据信息时还要获取数据发送方的有关属性包括IP地址和端口号要将struct sockadd_in* 转为更适合传输的struct sockadd*类型。 例如以下代码从创建好的socket文件描述符sock_fd中接收数据并输出接收到的信息 #include stdio.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include string.hint main() {int sock_fd socket(AF_INET, SOCK_DGRAM, 0);if (sock_fd -1) {printf(Failed to create socket!\n);return -1;}struct sockaddr_in serv_addr;memset(serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family AF_INET;serv_addr.sin_addr.s_addr inet_addr(127.0.0.1);serv_addr.sin_port htons(8888);if (bind(sock_fd, (struct sockaddr *)serv_addr, sizeof(serv_addr)) -1) {printf(bind error!\n);return -1;}char buf[1024] {0};struct sockaddr_in cli_addr;socklen_t cli_len sizeof(cli_addr);ssize_t recv_len recvfrom(sock_fd, buf, sizeof(buf), 0, (struct sockaddr *)cli_addr, cli_len);if (recv_len -1) {printf(recvfrom error!\n);return -1;}printf(Received message from %s:%d, message: %s\n, inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);close(sock_fd);return 0; }此处为UDP服务器代码创建套接字进行bind()操作后等待客户端发送数据使用recvfrom()函数接收数据然后输出接收到的信息。 #pragma once#include iostream #include cerrno #include cstring #include cstdlib #include functional #include strings.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include pthread.h #includeunistd.h #include unordered_map using namespace std;class udpserver {public: udpserver(std::string ip,int port):_sockfd(-1),_port(port),_ip(ip) {} bool InitServer() {//创建套接字_sockfdsocket(AF_INET,SOCK_DGRAM,0);//AF_INET//表示要进行网络通信SOCK_DGRAM UDP协议if(_sockfd0){//表示创建套接字失败std::cout socket error;return false;}std::cout socket create success,socfd:_sockfd std::endl;struct sockaddr_in local;memset(local,\0,sizeof(local));//清空结构体local.sin_familyAF_INET;local.sin_porthtons(_port);local.sin_addr.s_addrinet_addr(_ip.c_str());//绑定if(bind(_sockfd,(struct sockaddr*)local,sizeof(sockaddr))0){std::coutbond errorstd::endl;return false;}std::coutbond successstd::endl;return true;}void Start() {#define SIZE 1024 char buffer[SIZE];while(true){struct sockaddr_in perr;socklen_t lensizeof(perr);//读取数据ssize_t sizerecvfrom(_sockfd,buffer,sizeof(buffer)-1,0,(struct sockaddr*)perr,len);if(size0)//读取失败{std::coutrecvfrom cerrorstd::endl;}else{buffer[size]\0;int portntohs(perr.sin_port);std::string ipinet_ntoa(perr.sin_addr);std::coutip: port# bufferstd::endl;}} } ~udpserver() {if(_sockfd0){close(_sockfd);//关闭文件描述符} } private: int _sockfd;//网络文件描述符 int _port;//端口号 std::string _ip;//IP地址};#includeserver.hpp int main(int argc,char*argv[]) {if(argc!2){std:coutusage:argv[0] portstd::endl;return 1;}std::string ip127.0.0.1;int portatoi(argv[0]);udpserver* sernew udpserver(ip,port);ser-InitServer();ser-Start();return 0; } 客户端套接字的创建和绑定 客户端在创建套接字时参数的传递与服务端创建套接字时一样都是AF_INET, SOCK_DGRAM, 0不同的是服务端需要进行端口号绑定而客户端不需要。 但在网络通信通信双方都需要找到对方因此服务端和客户端都需要有各自的IP地址和端口号只不过服务端需要进行端口号的绑定而客户端不需要。 因为服务器就是为了给别人提供服务的因此服务器必须要让别人知道自己的IP地址和端口号IP地址一般对应的就是域名而端口号一般没有显示指明过因此服务端的端口号一定要是一个众所周知的端口号并且选定后不能轻易改变否则客户端是无法知道服务端的端口号的这就是服务端要进行绑定的原因只有绑定之后这个端口号才真正属于自己因为一个端口只能被一个进程所绑定服务器绑定一个端口就是为了独占这个端口。 而客户端在通信时虽然也需要端口号但客户端一般是不进行绑定的客户端访问服务端的时候端口号只要是唯一的就行了不需要和特定客户端进程强相关。 客户端不需要绑定端口号是因为客户端的套接字在创建时会自动由操作系统分配一个随机端口号并且这个随机端口号会在套接字连接到服务器端时被发送给服务器端因此服务器端就可以使用该端口号来与客户端进行数据传输。客户端套接字的随机端口号一般是在1024到65535之间的一个空闲端口号这样可以避免与其他已知端口号冲突。 如果客户端绑定了某个端口号那么以后这个端口号就只能给这一个客户端使用就是这个客户端没有启动这个端口号也无法分配给别人并且如果这个端口号被别人使用了那么这个客户端就无法启动了。所以客户端的端口只要保证唯一性就行了因此客户端端口可以动态的进行设置并且客户端的端口号不需要我们来设置当我们调用类似于sendto这样的接口时操作系统会自动给当前客户端获取一个唯一的端口号。 也就是说客户端每次启动时使用的端口号可能是变化的此时只要我们的端口号没有被耗尽客户端就永远可以启动。 #pragma once #include iostream #include string #include cstring #includeunistd.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include arpa/inet.hclass udpclient { public:udpclient(std::string server_ip,int server_port):_sockfd(-1),_server_port(server_port),_server_ip(server_ip){}bool Initclient(){//创建套接字_sockfdsocket(AF_INET,SOCK_DGRAM,0);//AF_INET//表示要进行网络通信SOCK_DGRAM UDP协议if(_sockfd0){//表示创建套接字失败std::cout socket error;return false;}return true;}udpclient(){if(_sockfd0){close(_sockfd);//关闭文件描述符}}private:int _sockfd;//文件描述符int _server_port;//服务端端口号std::string _server_ip;//服务端的IP地址 }; 当客户端与服务端进行绑定后接下来就是要向对方发送消息进行通信了。 UDP通信中的sendto函数用于向指定的IP地址和端口号发送数据报。该函数的调用格式如下 int sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);参数说明 sockfd要发送数据的套接字文件描述符。buf待发送的数据指针。len待发送的数据长度。flags发送标志一般为0。dest_addr指向目的地址结构体的指针需要将IP地址和端口号分别填入该结构体的sin_addr和sin_port成员中。addrlen目的地址结构体的长度。 调用sendto函数时需要填写目的地址结构体例如 struct sockaddr_in dest_addr; dest_addr.sin_family AF_INET; dest_addr.sin_port htons(port); dest_addr.sin_addr.s_addr inet_addr(ip);其中port和ip分别为目的端口号和IP地址字符串。 sendto函数会将指定的数据报发送到指定的目的地址如果发送成功返回发送的字节数如果失败返回-1并设置全局errno变量的值。由于UDP是无连接的因此在发送数据时不需要建立连接。 UDP通信中的sendto函数用于向指定的IP地址和端口号发送数据报。该函数的调用格式如下 int sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);参数说明 sockfd要发送数据的套接字文件描述符。buf待发送的数据指针。len待发送的数据长度。flags发送标志一般为0。dest_addr指向目的地址结构体的指针需要将IP地址和端口号分别填入该结构体的sin_addr和sin_port成员中。addrlen目的地址结构体的长度。 调用sendto函数时需要填写目的地址结构体例如 struct sockaddr_in dest_addr; dest_addr.sin_family AF_INET; dest_addr.sin_port htons(port); dest_addr.sin_addr.s_addr inet_addr(ip);其中port和ip分别为目的端口号和IP地址字符串。 sendto函数会将指定的数据报发送到指定的目的地址如果发送成功返回发送的字节数如果失败返回-1并设置全局errno变量的值。由于UDP是无连接的因此在发送数据时不需要建立连接。 #pragma once #include iostream #include string #include cstring #includeunistd.h #include sys/types.h #include sys/socket.h #include netinet/in.h #include arpa/inet.hclass udpclient { public:udpclient(std::string server_ip,int server_port):_sockfd(-1),_server_port(server_port),_server_ip(server_ip){}bool Initclient(){//创建套接字_sockfdsocket(AF_INET,SOCK_DGRAM,0);//AF_INET//表示要进行网络通信SOCK_DGRAM UDP协议if(_sockfd0){//表示创建套接字失败std::cout socket error;return false;}return true;}void Start(){std::string msg;struct sockaddr_in perr;memset(perr,\0,sizeof(perr));perr.sin_familyAF_INET;perr.sin_porthtons(_server_port);perr.sin_addr.s_addrinet_addr(_server_ip.c_str());while(true){std::coutPlease Enter#;getline(std::cin,msg);sendto(_sockfd,msg.c_str(),msg.size(),0,(struct sockaddr*)perr,sizeof(perr));//std::coutsendto() successstd::endl;}}udpclient(){if(_sockfd0){close(_sockfd);//关闭文件描述符}}private:int _sockfd;//文件描述符int _server_port;//服务端端口号std::string _server_ip;//服务端的IP地址 }; #includeclient.hpp int main(int argc,char*argv[]) {if(argc!3){std::coutusage:argv[0] portstd::endl;return 1;}std::string server_ipargv[1];int server_portatoi(argv[2]);udpclient* clinew udpclient(server_ip,server_port);cli-Initclient();cli-Start();return 0; }
http://www.hkea.cn/news/14578175/

相关文章:

  • 淘宝便宜的团购网站建设网站开发人员的职责是什么
  • 网站建设远程培训360网站备案查询
  • 百度宣传做网站多少钱oa网站建设推广
  • 自己做的网站怎么发到网上资源网站搭建
  • 网站站外优化wordpress顶部菜单
  • apt安装wordpress推广优化师
  • 做网站应该了解什么深圳市建设银行网站
  • 广州建站公司兴田德润活动男女做那个网站动态图片
  • 网站最好推广的方式知名网站域名被抢注
  • 遵义网站制作如何收费seo整站优化服务教程
  • 多与pR值高的网站做链接app下载安装官方免费下载
  • 网站怎么做自然优化凡科建站提示网站建设中
  • 深圳网页设计与制作工资多少钱互联网推广seo
  • 昆明网站建设技术研发中心永久免费网址在线观看电视剧
  • 哪个外贸网站开发客户比较好用抖音代运营服务方案
  • 网站建设记账安阳县事业单位招聘2021
  • iis7 网站无法显示该页面太原企业模板建站
  • 网站上传的视频播放卡wordpress 标签页制作
  • 学网站开发要下载哪些软件有哪里可以做兼职翻译的网站
  • 中建八局土木建设有限公司网站网站建设管理汇报
  • 兰州房地产网站建设微商城开发小程序开发
  • 梅州网站优化公司百科网站推广
  • 专门做顶账房的网站清溪做网站的电话
  • 网站备案号查不到邳州城乡住房和城乡建设网站
  • 网站制作及排名优化东城免费做网站
  • 响应式网站方案wordpress修改作者信息
  • 各大网站投稿邮箱网络营销的理论基础
  • 网站二次开发的模板种类简单网站建设软件
  • 网站代码字体变大电子商务网站设计原理名词解释
  • 自己在公司上班做网站宣传 侵权吗山东网站备案注销