linux网络编程之Socket编程

(1)socket套接字

             1)在linux环境下,socket用于表示进程间网络通信的特殊文件类型,其本质是内核借助缓冲区形成的伪文件(不占磁盘空间,除此之外还有二进制文件,管道,字符文件)。

             2)伪文件也可以像文件一样的操作(读写),区别在于管道用于本地进程间的通信套接字多用于网络进程间数据的传递。 

             3)在TCP/IP协议中,IP地址可以在网络环境中唯一标识一个主机,端口号则在主机中唯一标识一个进程。因此在网络中,IP地址+端口号就对应一个socket

             4)在网络通信中,套接字一定成对存在。一段的发送缓冲区对应对端的接收缓冲区,使用同一个文件描述符可以操作发送缓冲区和接收缓存区。(全双工,文件描述符一个,数据缓存区两个

(2)网络字节序

              1)大端字节序:低地址高位、高地址低位

                    小端字节序:低地址低位,高地址高位(windows)

             2)网络数据流地址规定:先发出的数据是低地址,后发出的数据是高地址。

                   TCP/IP协议规定,网络数据流采用大端字节序,即低地址高字节。

             3)为了保证网络程序具有可移植性,需要调用库函数做网络字节序和主机字节序的转换。 

                            #include<arpa/inet.h>

                           uint32_t   htonl(uint32_t   hostlong);  //host to net long   IP

                           uint16_t   htons(uint16_t   hostshort);  //host to net short port 

                           uint32_t   ntohl(uint32_t   netlong); //net  to host  long  IP 

                           uint16_t   ntohl(uint16_t   netshort);  //net  to host  short port  

             如果主机是小端字节序,这些函数将参数做相应的大小端转换后返回。如果主机是大端字节序,则不做转换。

(3)IP地址转换

            1)通常我们所说的IP地址(如192.168.1.200),属于点分十进制形式,而我们在网络传输中通常使用到的是网络字节序形式,因此在传输的过程中,首先需要把点分十进制形式的字符串转换为网络字节序格式。

            2)IP地址转换函数

                      #include<arpa/inet.h>

                int    inet_pton(int af  ,const char *src, void *dst);//点分十进制字符串转换为网路字节序

               const  char *inet_ntop(int af, const void *src, char *dst, socklen_t size);//网络字节序转换为点分十进制

                参数:af(IP地址格式):AF_INET(IPV4)            AF_INET6(IPV6)

          3)sockaddr数据结构

            struct sockaddr诞生于IPV4协议时代,函数的接口通常使用(struct sockaddr),但是现在为了兼容IPV6,将struct sockaddr 改变成了struct sockaddr_t格式(因此现在定义变量时使用struct sockaddr_t,在传参数时使用struct sockaddr(不能直接用这个定义变量)

                                               

struct  sockaddr{                               struct sockaddr_in{                                                    struct in_addr{

          sa_family_t    sa_family;            _kernel_sa_family_t     sin_family;  //地址结构类型              _be32 s_addr;IP地址

          char  sa_data[14];                     _be16             sin_port;   //端口号                              };

};                                                             struct  in_addr  sin_addr;

                                                                                   ......

                                                                              };

 (4)Socket模型创建流程图

                 注:TCP客户端没有调用bind()函数绑定IP和端口号,系统会自动给它分配IP和端口号,但在TCP服务端则不能省去bind()函数。

         

(5)网络套接字函数

                   头文件:#include<sys/types.h>

                                   #include<sys/socket.h>

            1)打开一个网络通讯端口:socket函数(服务端、客户端)

                      int   socket(int domain, int type ,int protocol);

                     参数:domain:协议类型,AF_INET(IPV4)   AF_INET6(IPV6)     AF_UNIX(本地协议)

                                 type:SOCK_STREAM(流失协议,默认为TCP传输)       SOCK_DGRAM(报式协议,默认使用UDP传输)

                                 protocol:使用默认协议

                    返回值:成功返回新创建socket的文件描述符,失败返回-1.

         2)绑定IP和端口号:bind函数(服务端/客户端)

                       int   bind(int sockfd ,  const struct sockaddr *addr, socklen_t  addrlen);

               参数:sockfd : socket 文件描述符

                           addr:绑定了IP和端口号的结构体

                          addrlen:sizeof(addr)长度

              返回值:成功返回0,失败返回-1.

        3)指定监听上限数(同一时间允许多少客户端和服务器连接):listen函数(服务端)

              int   listen(int   sockfd,  int  backlog)

                   参数:backlog:排队进行三次握手队列和刚刚建立三次握手队列的链接数和。

                   返回值:成功返回0,失败返回-1

      4)接收连接请求:accept函数(服务端调用)

            int accept(int  sockfd,struct  sockaddr *addr,socklen_t *addrlen);

                  参数:addr(传出参数)返回链接客户端地址信息,含IP和端口号。

      5)连接客户端:connect函数(客户端调用)

            int   connect(int  sockfd,const struct *sockaddr,socklen_t addrlen)

                 参数:addr:传入参数,指定服务器的地址信息,含IP地址和端口号。

                             addrlen:sizeof(addr)大小

                返回值:成功返回0,失败返回-1.

                            addrlen(传入传出参数):传入sizeof(addr)大小,函数返回真正接收到的地址结构体的大小。

                返回值:生成一个新的socket文件描述符,用于和客户端通信,失败返回-1

(6) C/S模型之TCP:实现最简单的客户端、服务器程序

             服务器端:可通过命令nc  +自己ip +端口号完成自我通信(在不同进程使用)nc 182.168.1.100 6666

               

            客户端:

          

猜你喜欢

转载自blog.csdn.net/xx18030637774/article/details/82496353