【C语言】【unix c】基于TCP传输层的编程模型
2017-09-28 23:09
183 查看
一、基于TCP传输层的编程模型 流程: 服务器上可以同时工作多个服务端,以一个服务端为例,一个服务端相当于一个设备,在LINUX下也就是一个文件,这个文件对应了一片存储区域,这个区域里记录各种信息。因此在建立服务端的时候需要先创建一个设备(文件)->创建好的设备里没有信息,我们需要添加一些信息来用于与外界的通信。我们知道要通信需要知道互相的ip,端口信息。所以我们将本机的ip地址和端口号与创建好的设备绑定,让该ip和端口的结合作为该设备的标示->自身准备好就需要与客户端建立链接,因此服务端就需要监听看看谁要链接服务端->发现请求对象后需要建立链接,建立链接的方式是创建一个用于通讯的文件,该通讯文件记录了客户链接本机的哪个服务端及谁连的。->链接成功后开始进行信息处理->处理完成后结束链接,但是服务端不会结束,继续监听。 服务器端的编程模型: 1、创建一个用于网络通信的设备(通讯端点)(创建一个文件描述符,这里的文件描述符是用于创建设备的) socket(2) #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); 功能:(套接口)创建一个用于通信的端点。 参数: domain:选择协议家族 AF_INET:应用于IPV4地址家族 AF_INET6:应用于IPV6地址家族 type: SOCK_STREAM:可靠的,基于链接的,双向的,队列式的 TCP SOCK_DGRAM:数据包 支持不可靠的,无链接的 UDP protocol:指定应用程序所使用的通信协议。在Internet中一般设置为0 0 返回值:返回一个新的文件描述符 -1 错误 errno设置 2、将这个通讯端点和本机的ip地址,端口号做绑定 bind(2) #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能:(将一本地地址与一套接口捆绑)绑定名字到地址,创建socket以后,socket中有地址空间,但是没有具体地址放到这个地址空间,我们需要将具体的地址和socket的地址空间绑定 参数: sockfd:已经创建好的socket,但是这个socket没有具体的地址 addr:指定了具体的地址,将这个地址绑定到socket中 addrlen:指定了addr的大小,是字节数 返回值:0 成功 -1 错误 errno被设置 3、在这个通讯端点监听客户端链接的到来,如果有链接到来,将到达的链接存放在缓冲区(队列的数据结构) listen(2) #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int listen(int sockfd, int backlog); 功能:(使套接字处于监听状态,该套接字将维护一个客户链接请求列对(未决链接队列))在scoket上监听链接,将socket标记为被动链接,接受即将到来的客户端请求,将链接追加到缓冲区,而accept将链接从队列取出 参数: sockfd:指定了被监听的socket backlog:指定了未决链接的最大数 返回值:0 成功 -1 错误 errno被设置 4、从这个缓冲区队列中取出一个客户端链接,返回一个链接描述符,用于和客户端的通信(这个链接描述符称为c_fd)(这里的文件描述符用于建立链接的,链接中断后是这里断开) accept(2) #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 功能:在socket上接收一个链接,从未决链接队列里取出第一个链接请求 参数: sockfd:指定了监听的socket addr:在这个地址空间里填充了客户端的地址和端口号,如果填为NULL则不会填充addrlen也设置为NULL addrlen:空间里指定了addr的长度 返回值:返回一个非负的整数,就是链接描述符 -1 错误 errno被设置 5、使用c_fd和客户端通信 a、获取客户端的请求 read(2) b、处理客户端的请求 write(2) c、响应客户端 6、关闭c_fd,终止和客户端通信 close(2) 客户端的编程模型: 1、创建一个用于通信的设备(通信端点) socket(2) 2、使用这个通信端点链接到服务器(需要知道服务器的IP和端口号) connect(2) #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 功能:在socket上发起一个链接 参数: sockfd:指定socket,将这个socket链接到addr的地址空间 addr:指定了具体的地址空间,要链接到的地址空间(服务器端的) addrlen:指定了addr的长度 返回值:0 成功 -1 错误 errno被设置 4000 3、向服务器发送消息 4、等待服务器端的响应 5、处理服务器的响应消息 6、关闭设备,结束通信 补充: 1、链接到达但是没有进行接通是未决链接 2、地址家族的通用结构:(通用结构是不能使用的,具体的使用结构和这个有点不一样) struct sockaddr { sa_family_t sa_family; //地址家族,一般都是AF_XXX的形式,常用AF_INET,代表TCP/IP协议族 char sa_data[14];//14字节的协议地址,指明地址信息,一般编程不会直接对此进行操作,而是用另一个与sockaddr等价的数据结构,像sockaddr_in } 3、与sockaddr等价的数据结构可以使用【man in.h】察看,常用的有IPV4,IPV6的数据结构 #include <netinet/in.h> in_port_t:uint16_t 无符号短整形 in_addr_t:uint32_t 无符号长整形/整形 IPV4具体的数据结构: struct sockaddr_in{ sa_family_t sin_family //AF_INET. 指协议族,这里只能用AF_INET in_port_t sin_port //Port number. 存储端口号(注意这里需要转换为网络字节序) struct in_addr sin_addr //IP address. 存储ip地址(需要使用in_addr这个数据结构) } sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向sockaddr的结构体,并替代他。也就是说可以用sockaddr_in建立需要的信息,然后进行类型转换就可以了(struct sockaddr*)mycket sa_family_t 在<sys/socket.h> 中定义 in_addr结构体: struct in_addr{ in_addr_t s_addr; } 本机ip地址初始化: INADDR_ANY :IPV4 local host address 是一个宏,宏的本质是一个整数。这个宏代表了本机所有的地址 4、端口号是0~65535 但是5000一下最好不用,已经被国际组织使用 5、系统提供了函数来处理本机字节序和网络字节序的问题: #include <arpa/inet.h> uint32_t htonl(uint32_t hostlong);//主机字节序转换为网络字节序 uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); h:host n:net s:short l:long t:to 6、ip地址的字符串格式和二进制格式间的互相转换 inet_pton(3) #include <arpa/inet.h> int inet_pton(int af, const char *src, void *dst); 功能:从字符串格式转换为二进制格式(ipv4和ipv6都支持) 参数: af: AF_INET:ipv4 AF_INET6:ipv6 src:字符串格式的ip地址 dst:存储了网络地址结构信息 返回值:1 成功 0 代表src无效 -1 错误 errno被设置 INET_NTOP(3) #include <arpa/inet.h> const char *inet_ntop(int af, const void *src,char *dst, socklen_t size); 功能:将二进制到字符串的转换 参数: af: AF_INET:ipv4 AF_INET6:ipv6 src:在struct in_addr dst:用于存储字符串的空间 size:指定了空间的有效字节数 返回值:非空,返回dst的地址,字符串的首地址 NULL 错误 errno被设置 127.0.0.1: 本地地址,环回地址,用于测试本机的网络设备工作是否正常 setsockopt()
相关文章推荐
- Unix高级编程:网络基础、基于TCP以及UDP的编程模型、TCP高并发编程模型
- 网络编程:基于TCP的socket网络传输视频(C++, python)
- java 网络编程 基于TCP ,UDP的网络传输
- socket编程 -- 基于TCP协议的C/S通信模型及实现
- 第13章 TCP编程(4)_基于自定义协议的多线程模型
- [C语言]基于TCP的基本C/S模型
- Linux 系统应用编程——网络编程(利用TCP/IP 模型分析数据传输过程)
- 第13章 TCP编程(3)_基于自定义协议的多进程模型
- 【C语言】【unix c】基于UDP的网络编程
- 网络编程 基于TCP的多文件传输程序(二)
- Linux网络编程之[基于socket通信的tcp协议的编程模型]
- Linux 系统应用编程——网络编程(利用TCP/IP 模型分析数据传输过程)
- UNIX网络高级编程第2章传输层UDP TCP和SCTP 2.2总图2.3用户数据报协议2.4传输控制协议2.5SCTP
- 基于TCP传输的网络编程异常处理
- 基于TCP的C/S网络编程模型
- 孙鑫VC视频教程笔记之第十四课“基于TCP和UDP的Socket编程”
- Qt5 基于TCP传输的发送/接收文件服务器(支持多客户端)
- UNIX下c语言的图形编程--curses.h 函式库(2)
- 基于Socket的UDP和TCP编程介绍
- Java 网络编程三 TCP传输协议(例:传输文本、图片)