网站优化要用什么软件,手机网站怎么做微信登陆,济南建设银行公积金网站,云南网络营销公司认识端口号网络字节序处理字节序函数 htonl、htons、ntohl、ntohs socketsocket编程接口sockaddr结构结尾实现UDP程序的socket接口使用解析socket处理 IP 地址的函数初始化sockaddr_inbindrecvfromsendto 实现一个简单的UDP网络程序封装服务器相关代码封装客户端相关代码实验结… 认识端口号网络字节序处理字节序函数 htonl、htons、ntohl、ntohs socketsocket编程接口sockaddr结构结尾实现UDP程序的socket接口使用解析socket处理 IP 地址的函数初始化sockaddr_inbindrecvfromsendto 实现一个简单的UDP网络程序封装服务器相关代码封装客户端相关代码实验结果 认识端口号
我们把数据从A主机发送到B主机是目的吗不是真正通信的不是这两个机器其实是这两台机器上面的软件(人)
数据有IP(公网)标识一台唯一的主机用谁来标识各自主机上客户或者服务进程的唯一性呢? 为了更好的表示一台主机上服务进程的唯一性我们采用端口号port标识服务器进程客户端进程的唯一性!
端口号(port)是传输层协议的内容
端口号是一个2字节16位的整数端口号用来标识一个进程告诉操作系统当前的这个数据要交给哪一个进程来处理IP地址 端口号能够标识网络上的某一台主机的某一个进程一个端口号只能被一个进程占用 ip地址(主机全网唯一性) 该主机上的端口号标识该服务器上进程的唯一性 IP保证全网唯一port保证在主机内部的唯一性 主机上对应的服务进程在全网中是唯一的一个进程。 网络通信的本质其实就是进程间通信
需要让不同的进程先看到同一份资源—网络通信就是在做IO所以我们所有的上网行为无外乎两种我要把我的数据发出去、我要收到别人给我发的数据
进程已经有pid为什么要有port呢?
系统是系统网络是网络单独设置—系统与网络解耦需要客户端每次都能找到服务器进程—服务器的唯一性不能做任何改变— IPport不能随意改变不会轻易改变。不是所有的进程都要提供网络服务或者请求但是所有的进程都需要pid。
进程port–网络服务进程 底层OS如何根据port找到指定的进程OS内部采用hash方案在OS内部维护了一个基于端口号的哈希表key就是端口号value就是task_struct的地址。有这个端口号就可以找到PCB继而找到文件描述符表文件描述符对象对象找到了那么这个文件的缓冲区也就能找到然后就可以将数据拷贝到缓冲区最后就相当于我们将网络数据放到了文件中如同读文件一样就将数据读上去了。 一个进程可以绑定多个端口号但是一个端口号不能被多个进程绑定 理解源端口号和目的端口号 传输层协议(TCP和UDP)的数据段中有两个端口号分别叫做源端口号和目的端口号。 就是在描述 “数据是谁发的要发给谁”
认识TCP(Transmission Control Protocol 传输控制协议)协议:
传输层协议有连接相当于打电话必须先接通才能通话可靠传输面向字节流 认识UDP协议
认识UDP(User Datagram Protocol 用户数据报协议)协议:
传输层协议无连接相当于发送邮件只需要知道你的邮箱地址不需要你同意直接就能发给你不可靠传输面向数据报 网络字节序
我们已经知道内存中的多字节数据相对于内存地址有大端和小端之分磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分网络数据流同样有大端小端之分。那么如何定义网络数据流的地址呢
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出接收主机把从网络上接到的字节依次保存在接收缓冲区中也是按内存地址从低到高的顺序保存因此网络数据流的地址应这样规定先发出的数据是低地址后发出的数据是高地址。TCP/IP协议规定网络数据流应采用大端字节序即低地址高字节。不管这台主机是大端机还是小端机都会按照这个TCP/IP规定的网络字节序来发送/接收数据如果当前发送主机是小端就需要先将数据转成大端否则就忽略直接发送即可 为使网络程序具有可移植性使同样的C代码在大端和小端计算机上编译后都能正常运行可以调用以下库函数做网络字节序和主机字节序的转换 这些函数名很好记h表示hostn表示networkl表示32位长整数s表示16位短整数。例如htonl表示将32位的长整数从主机字节序转换为网络字节序例如将IP地址转换后准备发送。如果主机是小端字节序这些函数将参数做相应的大小端转换然后返回如果主机是大端字节序这些函数不做转换将参数原封不动地返回。
处理字节序函数 htonl、htons、ntohl、ntohs 函数原型
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);函数作用 将数据在不同字节序之间进行转换。
函数的详细介绍
htonl() 函数将一个 32 位无符号整数unsigned int从本地字节序转换为网络字节序大端字节序。htons() 函数将一个 16 位无符号整数unsigned short从本地字节序转换为网络字节序大端字节序。ntohl() 函数将一个 32 位无符号整数unsigned int从网络字节序大端字节序转换为本地字节序。ntohs() 函数将一个 16 位无符号整数unsigned short从网络字节序大端字节序转换为本地字节序。 socket
socket编程接口
// 创建 socket 文件描述符 (TCP/UDP, 客户端 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
// 开始监听socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr* address,socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);网络套接字编程多应用于网络跨主机之间多主机通信、支持本地通信原始套接字可以跨过传输层向下访问更底层的接口unix或间套接字仅本地通信
按道理要实现上述三种套接字应该要三套不同的接口但是设计者只设计了一套接口通过不同的参数解决所有网络或其他场景下的通信问题
sockaddr结构
socket API是一层抽象的网络编程接口适用于各种底层网络协议如IPv4、IPv6,以及后面要讲的UNIX Domain Socket。然而各种网络协议的地址格式并不相同
IPv4和IPv6的地址格式定义在netinet/in.h中IPv4地址用sockaddr_in结构体表示包括16位地址类型16位端口号和32位IP地址。IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6。 这样只要取得某种sockaddr结构体的首地址不需要知道具体是哪种类型的sockaddr结构体就可以根据地址类型字段确定结构体中的内容。socket API可以都用struct sockaddr *类型表示在使用的时候需要强制转化成sockaddr_in 这样的好处是程序的通用性可以接收IPv4IPv6以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数
sockaddr 结构
struct sockaddr{__SOCKADDR_COMMON (sa_); /* Common data: address family and length. */char sa_data[14]; /* Address data. */};sockaddr_in 结构
/* Structure describing an Internet socket address. */
struct sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port; /* Port number. */struct in_addr sin_addr; /* Internet address. *//* Pad to size of struct sockaddr. */unsigned char sin_zero[sizeof (struct sockaddr) -__SOCKADDR_COMMON_SIZE -sizeof (in_port_t) -sizeof (struct in_addr)];};虽然socket api的接口是sockaddr但是我们真正在基于IPv4编程时使用的数据结构是sockaddr_in这个结构里主要有三部分信息地址类型、端口号、IP地址。
in_addr结构
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};in_addr用来表示一个IPv4的IP地址。其实就是一个32位的整数。
显示当前户籍UDP连接状况与端口号的使用情况
sudo netstat -nuap结尾实现UDP程序的socket接口使用解析
socket
int socket(int domain, int type, int protocol);函数作用 用于创建一个新的网络套接字的系统调用。
函数参数 domain 参数指定了网络协议族:
AF_INET 表示 IPv4 协议AF_INET6 表示 IPv6 协议AF_UNIX 表示 Unix 域协议
type 参数指定了套接字的类型
SOCK_STREAM 表示面向连接的流套接字SOCK_DGRAM 表示无连接的数据报套接字SOCK_RAW 表示原始套接字。
protocol 参数指定了使用的协议
IPPROTO_TCP 表示 TCP 协议IPPROTO_UDP 表示 UDP 协议参数设置为 0 时系统会根据指定的 domain 和 type 参数选择一个默认的协议。这通常是最常用的协议例如对于 AF_INET 和 SOCK_STREAM 的组合通常使用的协议是 TCP即 IPPROTO_TCP。
使用 socket() 函数的一般流程如下
创建一个套接字调用 socket() 函数指定 domain、type 和 protocol 参数返回一个新的套接字描述符。绑定套接字到本地地址调用 bind() 函数将套接字和一个本地地址绑定以便其他程序可以通过该地址找到该套接字。监听连接请求如果创建的是面向连接的流套接字可以调用 listen() 函数开始监听连接请求。接受连接请求如果创建的是面向连接的流套接字可以调用 accept() 函数接受一个连接请求返回一个新的套接字描述符用于与客户端通信。发送和接收数据调用 send() 和 recv() 函数向对方发送数据或接收对方发送的数据。关闭套接字调用 close() 函数关闭套接字描述符释放相关资源。
处理 IP 地址的函数 int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);inet_aton() 函数将一个字符串形式的 IP 地址转换为一个二进制形式的 IP 地址。如果转换成功函数返回非零值否则返回零。inet_addr() 函数将一个字符串形式的 IP 地址转换为一个 32 位的整数该整数表示为网络字节序。如果转换成功函数返回一个非零值即返回一个网络字节序表示的 IP 地址否则返回 INADDR_NONE。inet_network() 函数将一个字符串形式的 IP 地址的网络部分转换为一个 32 位的整数该整数表示为网络字节序。inet_ntoa() 函数将一个二进制形式的 IP 地址转换为一个字符串形式的 IP 地址。注意该函数返回的是一个指向静态缓冲区的指针因此不要将其作为返回值传递给其他函数。inet_makeaddr() 函数根据网络号和主机号创建一个 IP 地址。inet_lnaof() 函数从一个二进制形式的 IP 地址中提取主机号部分。inet_netof() 函数从一个二进制形式的 IP 地址中提取网络号部分。
初始化sockaddr_in
sockaddr_in是一个 IPv4 地址结构体用于存储 IP 地址和端口号信息。在使用套接字函数时通常需要将地址信息存储在 sockaddr_in 结构体中并将其作为参数传递给函数 struct sockaddr_in local; // 定义了一个变量栈用户bzero(local, sizeof(local));//用于将指定的内存区域清零local.sin_family AF_INET;//将结构体成员 sin_family 设置为 AF_INET表示使用 IPv4 地址族local.sin_port htons(_port); //结构体成员 sin_port 设置为要使用的端口号使用 htons() 函数将端口号转换为网络字节序大端字节序local.sin_addr.s_addr inet_addr(_ip.c_str());//将结构体成员 sin_addr 设置为要使用的 IP 地址使用 inet_addr() 函数将 IP 地址转换为网络字节序大端字节序//在实际开发中可以使用 inet_pton() 函数将字符串形式的 IP 地址转换为一个 struct in_addr 类型的结构体该结构体包含了 IP 地址的二进制表示bind
int bind(int socket, const struct sockaddr *address,socklen_t address_len);函数作用 用于将一个本地地址IP 地址和端口号与一个套接字关联起来的函数
函数参数
socket 参数是一个指定了套接字的文件描述符。addr 参数是一个指向 struct sockaddr 类型的结构体的指针该结构体包含了要绑定的本地地址信息。addrlen 参数是 addr 结构体的长度
函数返回值 返回值为 0 表示绑定成功-1 表示绑定失败错误码保存在 errno 变量中。
recvfrom
ssize_t recvfrom(int socket, void *restrict buffer, size_t length,int flags, struct sockaddr *restrict address,socklen_t *restrict address_len);函数作用 用于从已连接或未连接的套接字接收数据的函数
函数参数
socket 参数是指定了要接收数据的套接字的文件描述符。buf 参数是一个指向接收数据的缓冲区的指针。len 参数是缓冲区的大小。flags 参数是一组标志位可以用来指定接收数据的行为。为0表示默认address 参数是一个指向 struct sockaddr 类型的结构体的指针用于存储发送数据的远程地址。addrlen 参数是 src_addr 结构体的长度。
函数返回值 函数返回值为接收到的数据的字节数如果没有数据可用则返回 0。如果发生错误则返回 -1错误码保存在 errno 变量中
sendto
ssize_t sendto(int socket, const void *message, size_t length,int flags, const struct sockaddr *dest_addr,socklen_t dest_len);函数作用 用于向已连接或未连接的套接字发送数据的函数
函数参数
socket 参数是指定了要发送数据的套接字的文件描述符。buf 参数是一个指向要发送数据的缓冲区的指针。len 参数是要发送数据的字节数。flags 参数是一组标志位可以用来指定发送数据的行为。dest_addr 参数是一个指向 struct sockaddr 类型的结构体的指针用于指定接收数据的远程地址。dest_len 参数是 dest_addr 结构体的长度。
函数返回值 函数返回值为发送数据的字节数如果发生错误则返回 -1错误码保存在 errno 变量中。 实现一个简单的UDP网络程序
封装服务器相关代码
udpServer.hpp
#pragma once#include iostream
#include string
#include strings.h
#include cerrno
#include cstring
#include cstdlib
#include functional
#include unistd.h
#include sys/types.h
#include sys/socket.h
#include arpa/inet.h
#include netinet/in.hnamespace Server
{using namespace std;static const string defaultIp 0.0.0.0; //TODOstatic const int gnum 1024;enum {USAGE_ERR 1, SOCKET_ERR, BIND_ERR};class udpServer{public:udpServer(const uint16_t port, const string ip defaultIp):_port(port), _ip(ip), _sockfd(-1){}void initServer(){// 1. 创建socket_sockfd socket(AF_INET, SOCK_DGRAM, 0);if(_sockfd -1){cerr socket error: errno : strerror(errno) endl;exit(SOCKET_ERR);}cout socket success: : _sockfd endl;// 2. 绑定portip(TODO)// 未来服务器要明确的port不能随意改变struct sockaddr_in local; // 定义了一个变量栈用户bzero(local, sizeof(local));local.sin_family AF_INET;local.sin_port htons(_port);local.sin_addr.s_addr inet_addr(_ip.c_str());//local.sin_addr.s_addr htonl(INADDR_ANY); // 任意地址bind服务器的真实写法int n bind(_sockfd, (struct sockaddr*)local, sizeof(local));if(n -1){cerr bind error: errno : strerror(errno) endl;exit(BIND_ERR);}// UDP Server 的预备工作完成}void start(){// 服务器的本质其实就是一个死循环char buffer[gnum];for(;;){// 读取数据struct sockaddr_in peer;socklen_t len sizeof(peer); //必填ssize_t s recvfrom(_sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)peer, len);// 1. 数据是什么 2. 谁发的if(s 0){buffer[s] 0;string clientip inet_ntoa(peer.sin_addr); //1. 网络序列 2. int-点分十进制IPuint16_t clientport ntohs(peer.sin_port);string message buffer;cout clientip [ clientport ]# message endl;}}}~udpServer(){}private:uint16_t _port;string _ip; // 实际上一款网络服务器不建议指明一个IPint _sockfd;// func_t _callback; //回调};
}udpServer.cc
#include udpServer.hpp
#include memoryusing namespace std;
using namespace Server;static void Usage(string proc)
{cout \nUsage:\n\t proc local_port\n\n;
}// ./udpServer port
int main(int argc, char *argv[])
{if(argc ! 2){Usage(argv[0]);exit(USAGE_ERR);}uint16_t port atoi(argv[1]);std::unique_ptrudpServer usvr(new udpServer(port));usvr-initServer();usvr-start();return 0;
}封装客户端相关代码
udpClient.hpp
#pragma once#include iostream
#include string
#include strings.h
#include cerrno
#include cstring
#include cstdlib
#include unistd.h
#include sys/types.h
#include sys/socket.h
#include arpa/inet.h
#include netinet/in.hnamespace Client
{using namespace std;class udpClient{public:udpClient(const string serverip, const uint16_t serverport) : _serverip(serverip),_serverport(serverport), _sockfd(-1), _quit(false){}void initClient(){// 创建socket_sockfd socket(AF_INET, SOCK_DGRAM, 0);if (_sockfd -1){cerr socket error: errno : strerror(errno) endl;exit(2);}cout socket success: : _sockfd endl;// 2. client要不要bind[必须要的]client要不要显示的bind需不需程序员自己bind不需要// 写服务器的是一家公司写client是无数家公司 -- 由OS自动形成端口进行bind-- OS在什么时候如何bind}void run(){struct sockaddr_in server;memset(server, 0, sizeof(server));server.sin_family AF_INET;server.sin_addr.s_addr inet_addr(_serverip.c_str());server.sin_port htons(_serverport);string message;while(!_quit){cout Please Enter# ;cin message;sendto(_sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)server, sizeof(server));}}~udpClient(){}private:int _sockfd;string _serverip;uint16_t _serverport;bool _quit;};
} // namespace ClientudpClient.cc #include udpClient.hpp
#include memoryusing namespace Client;static void Usage(string proc)
{cout \nUsage:\n\t proc server_ip server_port\n\n;
}// ./udpClient server_ip server_port
int main(int argc, char *argv[])
{if(argc ! 3){Usage(argv[0]);exit(1);}string serverip argv[1];uint16_t serverport atoi(argv[2]);unique_ptrudpClient ucli(new udpClient(serverip, serverport));ucli-initClient();ucli-run();return 0;
}实验结果 如有错误或者不清楚的地方欢迎私信或者评论指出
文章转载自: http://www.morning.snbry.cn.gov.cn.snbry.cn http://www.morning.tkchm.cn.gov.cn.tkchm.cn http://www.morning.trtdg.cn.gov.cn.trtdg.cn http://www.morning.clwhf.cn.gov.cn.clwhf.cn http://www.morning.rnnts.cn.gov.cn.rnnts.cn http://www.morning.wqcz.cn.gov.cn.wqcz.cn http://www.morning.yrbp.cn.gov.cn.yrbp.cn http://www.morning.kxsnp.cn.gov.cn.kxsnp.cn http://www.morning.mknxd.cn.gov.cn.mknxd.cn http://www.morning.nwtmy.cn.gov.cn.nwtmy.cn http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn http://www.morning.srgyj.cn.gov.cn.srgyj.cn http://www.morning.mlffg.cn.gov.cn.mlffg.cn http://www.morning.cpktd.cn.gov.cn.cpktd.cn http://www.morning.jrplk.cn.gov.cn.jrplk.cn http://www.morning.ktcfl.cn.gov.cn.ktcfl.cn http://www.morning.kongpie.com.gov.cn.kongpie.com http://www.morning.ydnx.cn.gov.cn.ydnx.cn http://www.morning.dqwykj.com.gov.cn.dqwykj.com http://www.morning.fgsct.cn.gov.cn.fgsct.cn http://www.morning.zzgtdz.cn.gov.cn.zzgtdz.cn http://www.morning.wkrkb.cn.gov.cn.wkrkb.cn http://www.morning.jqzns.cn.gov.cn.jqzns.cn http://www.morning.bpmdx.cn.gov.cn.bpmdx.cn http://www.morning.mhfbf.cn.gov.cn.mhfbf.cn http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn http://www.morning.ghqyr.cn.gov.cn.ghqyr.cn http://www.morning.hcbky.cn.gov.cn.hcbky.cn http://www.morning.bpmfq.cn.gov.cn.bpmfq.cn http://www.morning.qlsyf.cn.gov.cn.qlsyf.cn http://www.morning.jfwrf.cn.gov.cn.jfwrf.cn http://www.morning.cfjyr.cn.gov.cn.cfjyr.cn http://www.morning.kwwkm.cn.gov.cn.kwwkm.cn http://www.morning.cmrfl.cn.gov.cn.cmrfl.cn http://www.morning.dmwbs.cn.gov.cn.dmwbs.cn http://www.morning.ljhnn.cn.gov.cn.ljhnn.cn http://www.morning.wbqt.cn.gov.cn.wbqt.cn http://www.morning.ljbpk.cn.gov.cn.ljbpk.cn http://www.morning.tralution.cn.gov.cn.tralution.cn http://www.morning.lmrcq.cn.gov.cn.lmrcq.cn http://www.morning.twdwy.cn.gov.cn.twdwy.cn http://www.morning.ysrtj.cn.gov.cn.ysrtj.cn http://www.morning.a3e2r.com.gov.cn.a3e2r.com http://www.morning.fesiy.com.gov.cn.fesiy.com http://www.morning.xoaz.cn.gov.cn.xoaz.cn http://www.morning.qphgp.cn.gov.cn.qphgp.cn http://www.morning.yxmcx.cn.gov.cn.yxmcx.cn http://www.morning.tnkwj.cn.gov.cn.tnkwj.cn http://www.morning.nzfjm.cn.gov.cn.nzfjm.cn http://www.morning.ryxdf.cn.gov.cn.ryxdf.cn http://www.morning.syznh.cn.gov.cn.syznh.cn http://www.morning.npxcc.cn.gov.cn.npxcc.cn http://www.morning.pzpj.cn.gov.cn.pzpj.cn http://www.morning.wblpn.cn.gov.cn.wblpn.cn http://www.morning.gsjw.cn.gov.cn.gsjw.cn http://www.morning.ndcjq.cn.gov.cn.ndcjq.cn http://www.morning.pjtnk.cn.gov.cn.pjtnk.cn http://www.morning.csjps.cn.gov.cn.csjps.cn http://www.morning.mzjbz.cn.gov.cn.mzjbz.cn http://www.morning.qqnjr.cn.gov.cn.qqnjr.cn http://www.morning.bdypl.cn.gov.cn.bdypl.cn http://www.morning.mzhjx.cn.gov.cn.mzhjx.cn http://www.morning.ntyanze.com.gov.cn.ntyanze.com http://www.morning.hotlads.com.gov.cn.hotlads.com http://www.morning.kfbth.cn.gov.cn.kfbth.cn http://www.morning.qggcc.cn.gov.cn.qggcc.cn http://www.morning.pflpb.cn.gov.cn.pflpb.cn http://www.morning.pgxjl.cn.gov.cn.pgxjl.cn http://www.morning.tdldh.cn.gov.cn.tdldh.cn http://www.morning.uycvv.cn.gov.cn.uycvv.cn http://www.morning.lmmh.cn.gov.cn.lmmh.cn http://www.morning.ldspj.cn.gov.cn.ldspj.cn http://www.morning.bhbxd.cn.gov.cn.bhbxd.cn http://www.morning.cmzcp.cn.gov.cn.cmzcp.cn http://www.morning.hnpkr.cn.gov.cn.hnpkr.cn http://www.morning.ckcjq.cn.gov.cn.ckcjq.cn http://www.morning.lwwnq.cn.gov.cn.lwwnq.cn http://www.morning.xnfg.cn.gov.cn.xnfg.cn http://www.morning.pqypt.cn.gov.cn.pqypt.cn http://www.morning.ztmnr.cn.gov.cn.ztmnr.cn