邢台哪里做网站,临检中心网站建设,兰州新晨诚网络科技有限公司,有什么网站可以接单做兼职的目录
【1】字节序
1》大小端转换
2》端口转换 3》IP地址转换
主机字节序转换为网络字节序 #xff08;小端序-大端序#xff09;
网络字节序转换为主机字节序#xff08;大端序-小端序#xff09; 【2】TCP编程
1》流程
2》函数接口
1 socket
2 …目录
【1】字节序
1》大小端转换
2》端口转换 3》IP地址转换
主机字节序转换为网络字节序 小端序-大端序
网络字节序转换为主机字节序大端序-小端序 【2】TCP编程
1》流程
2》函数接口
1 socket
2 bind
3 listen
4 accept 5 recv 6 connect
7 send 3》代码展示
1服务器代码
2 客户端代码 4》改进版 1 服务器代码
2 客户端代码 【1】字节序
1》大小端转换 字节序不同类型的cpu主机内存存储大于一个字节类型的数据在内存中的存放顺序。 分类 小端序little-endian - 低序字节存储在低地址 (主机字节序) 大端序big-endian- 高序字节存储在低地址 (网络字节序) 网络中传输的数据必须使用网络字节序即大端字节序 终端显示的数据必须是主机字节序即小端字节序 写一个程序判断当前主机的字节序 测试方式共用体数据类型强转指针强转 共用体
#include stdio.hunion w
{short a;char b;
}c;int main(int argc, char const *argv[])
{c.a 0x12345678;printf(%#x\n,c.b); //0x78return 0;
} 数据类型强转、指针强转
#include stdio.hint main()
{
int a 0x12345678;
printf(数据类型强转 %#x\n,(char)a);
char *p(char *)a;
printf(指针强转%#x\n,*p);
return 0;
} 网络传输中,需要将每个主机的主机字节序(CPU决定),转换为网络中统一顺序的网络字节序才能供双方主机去识别。 只需要转换IP和port就可以,不需要转换传输的数据包的字节序因为IP和port为 4个字节和2个字节, 而数据报一般都为char类型, 占一个字节根据字节序的性质,内存存储大于一个字节类型的数据在内存中的存放顺序所以char类型并不具有字节序的概念。 2》端口转换
主机字节序转换为网络字节序小端序--大端序 u_long htonl (u_long hostlong); //host to internet long u_short htons (u_short short); //掌握这个 网络字节序转换为主机字节序大端序--小端序 u_long ntohl (u_long hostlong); u_short ntohs (u_short short); 3》IP地址转换 主机字节序转换为网络字节序 小端序-大端序 in_addr_t inet_addr(const char *strptr); //该参数是字符串 typedef uint32_t in_addr_t; struct in_addr { in_addr_t s_addr; }; 功能: 主机字节序转为网络字节序 参数: const char *strptr: 字符串 返回值: 返回一个无符号长整型数(无符号32位整数用十六进制表示), 否则NULL 网络字节序转换为主机字节序大端序-小端序 char *inet_ntoa(stuct in_addr inaddr); 功能: 将网络字节序二进制地址转换成主机字节序。 参数: stuct in_addr in addr : 只需传入一个结构体变量 返回值: 返回一个字符指针, 否则NULL; 【2】TCP编程
C/S架构client server B/S架构browser server
1》流程 服务器-------------------------------------------------------------------》接电话者 1 创建套接字socket---------------》有手机 2 指定网络信息---------------------------》有号码 3 绑定套接字bind------------------》绑定手机插卡 4 监听套接字listen-----------------》待机 5 接收客户端连接连接请求accept--》接电话 6 接收、发送数据recv send---》通话 7 关闭套接字close-----------------》挂电话 客户端-------------------------------------------------------------------》打电话者 1 创建套接字socket------------》有手机 2 指定服务器网络信息--------》有对方的号码 3 连接connect-------------------》拨打电话 4 接收发送消息recv send---》通话 5 关闭套接字close------------》挂电话 2》函数接口
1 socket int socket(int domain, int type, int protocol); 功能创建套接字 参数 domain协议族 AF_UNIX, AF_LOCAL 本地通信 AF_INET IPv4 AF_INET6 IPv6 type套接字类型 SOCK_STREAM:流式套接字 SOCK_DGRAM数据报套接字 SOCK_RAW原始套接字 protocol协议 - 填0 自动匹配底层 根据type 系统默认自动帮助匹配对应协议 传输层IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP 网络层htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL) 返回值 成功 文件描述符 失败 -1更新errno 2 bind int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 功能绑定 参数 socket套接字 addr用于通信结构体 (提供的是通用结构体需要根据选择通信方式填充对应结构体-通信当时socket第一个参数确定) addrlen结构体大小 返回值成功 0 失败-1,更新errno 通用结构体 struct sockaddr { sa_family_t sa_family; char sa_data[14]; } ipv4通信结构体 struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; }; struct in_addr { uint32_t s_addr; }; 本地通信结构体 struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[108]; /* pathname */ }; 3 listen int listen(int sockfd, int backlog); 功能:监听将主动套接字变为被动套接字 参数 sockfd套接字 backlog同时响应客户端请求链接的最大个数不能写0. 不同平台可同时链接的数不同一般写6-8个 (队列1保存正在连接) (队列2连接上的客户端) 返回值成功 0 失败-1,更新errno 4 accept int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); accept(sockfd,NULL,NULL); 功能阻塞函数阻塞等待客户端的连接请求如果有客户端连接 则accept()函数返回返回一个用于通信的套接字文件; 参数 Sockfd 套接字 addr 链接客户端的ip和端口号 如果不需要关心具体是哪一个客户端那么可以填NULL; addrlen结构体的大小 如果不需要关心具体是哪一个客户端那么可以填NULL; 返回值 成功文件描述符; //用于通信 失败-1更新errno 5 recv ssize_t recv(int sockfd, void *buf, size_t len, int flags); 功能: 接收数据 参数 sockfd acceptfd ; buf 存放位置 len 大小 flags 一般填0相当于read()函数 MSG_DONTWAIT 非阻塞 返回值 0 失败出错 更新errno 0 表示客户端退出 0 成功接收的字节个数 6 connect int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能用于连接服务器 参数 sockfdsocket函数的返回值 addr填充的结构体是服务器端的 addrlen结构体的大小 返回值 -1 失败更新errno 正确 0 7 send ssize_t send(int sockfd, const void *buf, size_t len, int flags); 功能发送数据 参数 sockfd:socket函数的返回值 buf发送内容存放的地址 len发送内存的长度 flags如果填0相当于write(); 3》代码展示
1服务器代码
#include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include string.hint main(int argc, char const *argv[])
{char buf[128] {0};// 1.创建套接字socket---------------》有手机int socketfd socket(AF_INET, SOCK_STREAM, 0);if (socketfd 0){perror(socket err\n);return -1;}printf(socketfd: %d\n, socketfd);// 2.指定(自己网络信息--------------------》有号码// struct sockaddr_in// {// sa_family_t sin_family; /* address family: AF_INET */// in_port_t sin_port; /* port in network byte order */// struct in_addr sin_addr; /* internet address */// };// /* Internet address. */// struct in_addr// {// uint32_t s_addr; /* address in network byte order */// };struct sockaddr_in saddr;saddr.sin_family AF_INET;//协议组 IPv4saddr.sin_port htons(8888);//端口号saddr.sin_addr.s_addr inet_addr(192.168.253.145);//本机地址// 3.绑定套接字bind------------------》绑定手机插卡if (bind(socketfd, (struct sockaddr *)saddr, sizeof(saddr)) 0){perror(bind err\n);return -1;}printf(bind ok\n);// 4.监听套接字listen-----------------》待机if (listen(socketfd, 6) 0){perror(listen err\n);return -1;}printf(listen ok\n);// 5.接收客户端连接连接请求accept--》接电话int acceptfd accept(socketfd, NULL, NULL);if (acceptfd 0){perror(accept err\n);return -1;}printf(acceptfd: %d\n, acceptfd);// 6.接收、发送数据recv send---》通话int ret;while (1){ret recv(acceptfd, buf, sizeof(buf), 0);//接收客户端的数据if (ret 0){perror(recv error\n);return -1;}else if (ret 0)//客户端退出{printf(client exit\n);break;}else{printf(buf: %s\n, buf);//打印接收到的数据memset(buf, 0, sizeof(buf));//清空缓存区的数据防止影响下次接收}}// 7.关闭套接字close-----------------》挂电话close(acceptfd);close(socketfd);return 0;
}2 客户端代码
#include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include string.hint main(int argc, char const *argv[])
{char buf[128] {0};// 1.创建套接字socket------------》有手机int socketfd socket(AF_INET, SOCK_STREAM, 0);if (socketfd 0){perror(socket err\n);return -1;}printf(%d\n, socketfd);// 2.指定服务器网络信息--------》有对方的号码struct sockaddr_in saddr;saddr.sin_family AF_INET;saddr.sin_port htons(8888);saddr.sin_addr.s_addr inet_addr(192.168.253.145);// 3.连接connect-------------------》拨打电话if (connect(socketfd, (struct sockaddr *)saddr, sizeof(saddr)) 0){perror(connect err\n);return -1;}printf(connect ok\n);// 4.接收发送消息recv send---》通话while (1){scanf(%s, buf);//输入数据// fgets(buf,sizeof(buf),stdin);if(strcmp(buf,exit)0)//判断是否为exit{break;}// write(socketfd, buf, sizeof(buf));send(socketfd, buf, sizeof(buf), 0);//发送到服务器}// 5.关闭套接字close------------》挂电话close(socketfd);return 0;
}4》改进版 地址和端口都通过参数传入 自动获取本机地址0.0.0.0 增加来电显示功能显示客户端连入的地址 1 服务器代码
#include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include string.h
#include stdlib.hint main(int argc, char const *argv[])
{if (argc ! 2){perror(argc err\n);return -1;}char buf[128] {0};// 1.创建套接字socket---------------》有手机int socketfd socket(AF_INET, SOCK_STREAM, 0);if (socketfd 0){perror(socket err\n);return -1;}printf(socketfd: %d\n, socketfd);// 2.指定(自己网络信息--------------------》有号码// struct sockaddr_in// {// sa_family_t sin_family; /* address family: AF_INET */// in_port_t sin_port; /* port in network byte order */// struct in_addr sin_addr; /* internet address */// };// /* Internet address. */// struct in_addr// {// uint32_t s_addr; /* address in network byte order */// };struct sockaddr_in saddr,caddr;saddr.sin_family AF_INET;saddr.sin_port htons(atoi(argv[1]));saddr.sin_addr.s_addr inet_addr(0.0.0.0);//全局地址自动获取本机地址// saddr.sin_addr.s_addr INADDR_ANY;// 3.绑定套接字bind------------------》绑定手机插卡if (bind(socketfd, (struct sockaddr *)saddr, sizeof(saddr)) 0){perror(bind err\n);return -1;}printf(bind ok\n);// 4.监听套接字listen-----------------》待机if (listen(socketfd, 6) 0){perror(listen err\n);return -1;}printf(listen ok\n);// 5.接收客户端连接连接请求accept--》接电话while (1)//循环等待客户端链接{int len sizeof(caddr);int acceptfd accept(socketfd, (struct sockaddr *)caddr,len);if (acceptfd 0){perror(accept err\n);return -1;}printf(acceptfd: %d\n, acceptfd);printf(port: %d ip: %s\n,ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr));//来电显示显示客户端信息// 6.接收、发送数据recv send---》通话int ret;while (1){ret recv(acceptfd, buf, sizeof(buf), 0);if (ret 0){perror(recv error\n);return -1;}else if (ret 0){printf(client exit\n);break;}else{printf(buf: %s\n, buf);memset(buf, 0, sizeof(buf));}}// 7.关闭套接字close-----------------》挂电话close(acceptfd);}close(socketfd);return 0;
}2 客户端代码
#include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h
#include unistd.h
#include sys/socket.h
#include netinet/in.h
#include arpa/inet.h
#include string.h
#include stdlib.hint main(int argc, char const *argv[])
{if (argc ! 3){perror(argc err\n);return -1;}char buf[128] {0};// 1.创建套接字socket------------》有手机int socketfd socket(AF_INET, SOCK_STREAM, 0);if (socketfd 0){perror(socket err\n);return -1;}printf(%d\n, socketfd);// 2.指定服务器网络信息--------》有对方的号码struct sockaddr_in saddr;saddr.sin_family AF_INET;saddr.sin_port htons(atoi(argv[2]));saddr.sin_addr.s_addr inet_addr(argv[1]);// 3.连接connect-------------------》拨打电话if (connect(socketfd, (struct sockaddr *)saddr, sizeof(saddr)) 0){perror(connect err\n);return -1;}printf(connect ok\n);// 4.接收发送消息recv send---》通话while (1){// scanf(%s, buf);fgets(buf, sizeof(buf), stdin);if (strcmp(buf, exit\n) 0){break;}write(socketfd, buf, sizeof(buf));// send(socketfd, buf, sizeof(buf), 0);}// 5.关闭套接字close------------》挂电话close(socketfd);return 0;
}今天的分享就到这里结束啦如果有哪里写的不好的地方请指正。 如果觉得不错并且对你有帮助的话点个关注支持一下吧