网络编程(二)

    xiaoxiao2021-03-25  117

    网络编程基础(二)


    1、协议标准文件

    www.rfc-editor.org

    2、路由命令

    route -n netstat -r

    3、查看cpu和mem的命令

    cat /proc/cpuinfo cat /proc/meminfo

    4、查看系统版本号和系统位数

    cat /etc/issue uname -a
    5、sizeof和strlen的区别
    6、struct in_addr struct in_addr { unsigned long int s_addr; } //这个结构体中存储的是网络二进制的ip地址

    7、gethostbyname

    根据域名得到对应的物理ip地址 #include <netdb.h> struct hostent *gethostbyname(const char *name); //name:域名网址 //返回值: struct hostent { char *h_name; /* 正式的名字 */ char **h_aliases; /* 别名 */ int h_addrtype; /* 主机地址的类型 */ int h_length; /* 地址的长度 */ char **h_addr_list; /* 地址的列表 */ } #define h_addr h_addr_list[0] /* 第一个ip地址 */

    8、gethostbyaddr

    根据公共域名的ip地址(8.8.8.8)得到对应的域名 #include <sys/socket.h> /* for AF_INET */ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); //addr:ip地址,是网络二进制的ip地址 //len:ip地址的长度 //type:ip地址的类型 AF_INET(IPV4协议族)
    9、socket编程相关结构体 struct in_addr { unsigned long int s_addr; }; struct sockaddr { unsigned short sin_family; char data[14]; }; struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; /*sin_family 在socket编程中只能是AF_INET */ /*sin_port存储端口号(使用网络字节顺序),在linux下,端口号的范围0~65535,同时0~1024范围的端口号已经被系统使用或保留。*/ /*sin_zero[8]这8个字节是为了补全和struct sockaddr长度一样使用的*/ int len=0; len=sizeof(struct sockaddr);//16 len=sizeof(struct sockaddr_in);//16 //使用时是这样使用的 struct sockaddr_in server; (struct sockaddr *)&server;
    10、socket编程基本函数 socket() #include <sys/types.h> #include <sys/socket.h> //生成socket文件描述符 int socket(int domain, int type, int protocol); domain: AF_INET AF_INET6 AF_UNIX,AF_LOCAL type: SOCK_STREAM//tcp协议 SOCK_DGRAM//udp协议 protocol: IPPROTO_TCP IPPROTO_UDP /* 说明:如果domain和type确定了,protocol也就确定了,所以protocal可以写0,缺省默认 举例:socket(AF_INET,SOCK_STREAM,0)<=>socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) socket(AF_INET,SOCK_DGRAM,0)<=>socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP) 返回值: 成功返回socket文件文件描述符;失败返回-1 */ close() #include <unistd.h> int close(int fd); /* fd:socket文件描述符 返回值: 成功是0,错误是-1 */ send(write) #include <sys/types.h> #include <sys/socket.h> ssize_t send(int sockfd, const void *buf, size_t len, int flags); /* sockfd:socket生成的文件描述符 buf:收发数据的数组或结构体指针 len:收发数据的实际的长度 flags:一般取0; 返回值: 成功返回的是发送的字节数,失败返回-1 int len=0; len=send(sockfd,buf,sizeof(buf),0)<=>len=write(sockfd,buf,sizeof(buf)) */ recv(read) #include <sys/types.h> #include <sys/socket.h> ssize_t recv(int sockfd, void *buf, size_t len, int flags); 参数同Send 返回值: 返回正确接收的字节数; 出错返回-1; 如果返回值=0,说明对端socket已经关闭 send() recv()是socket专用的函数,socket数据的收发,或者说socket数据的读写,也是使用write() read() 11、tcp socket 循环服务器模型,支持一对一的连接 //客户端 socket() connect() #include <sys/types.h> #include <sys/socket.h> //通过3次握手和服务器的accept函数建立连接 int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); /* sockfd:socket生成的文件描述符 addr:(struct sockaddr *)&servaddr, struct sockaddr_in servaddr; addrlen:sizeof(servaddr) 返回值:成功返回0,出错返回-1 */ send()/write() recv()/read() close() //服务器 socket() bind() #include <sys/types.h> #include <sys/socket.h> /*把addr赋值的结构体变量绑定到sockfd,也就是说让socdfd具有addr这个结构体变量的属性,具有这样的family,port,addr */ int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); /* sockfd:socket生成的文件描述符 addr:(struct sockaddr *)&servaddr addrlen:sizeof(servaddr) 返回值: 成功返回0,出错返回-1 */ listen() #include <sys/types.h> #include <sys/socket.h> //监听,不阻塞的 int listen(int sockfd, int backlog); /* sockfd:socket生成的文件描述符 backlog:5~20,指的是客户端连接在服务器端的未完成队列和已完成队列的长度,这个长度并不是直接的5~20,5~20只是一个基数,具体的队列长度是经过一个算法得出的f(x)=x^3+x^2+x+1 [5,20] 返回值:成功返回0,出错返回-1 */ accept() #include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); /* sockfd:socket文件描述符 addr:(struct sockaddr *)&cliaddr addrlen:sizeof(cliaddr) 返回值: 成功返回的是新生成的和客户端连接对应的socket文件描述符,失败返回的是-1 */ recv()/read() send()/write() close()

    12、socket端到端

    socket的每一端是用IP+port表示的 port端口号 unsigned int (0~65535) 1)熟知端口(0~1023) http 80/8080 ftp 21/20 udp 520 ssl 139 2)扩展端口(1024~65535) 可以自定义的端口 自定义一个比较大的值,保证不重复

    13、udp socket

    已连接的udp socket和未连接的udp socket,本质上都是联通可以收发数据的;之所以有区分,是因为编写socket程序的代码形式不一样;如果客户端代码中有connect函数,是已连接的udp socket,如果客户端代码中没有connect函数,是未连接的udp socket //已连接的udp socket //客户端 socket() connect() send/write() recv/read() close() //服务器 socket() bind() recvfrom() #include <sys/types.h> #include <sys/socket.h> //recvfrom等价于acceptrecv函数的组合 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地址 addrlen:地址传递方式,客户端结构体的长度 返回值: 正确返回接收到的字节数;错误返回-1;如果返回0说明socket对端已经关闭 */ sendto() #include <sys/types.h> #include <sys/socket.h> //sendto函数相当于是connectsend函数的组合 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen); /* sockfd:socket文件描述符 buf:发送的数据存储的数组 len:发送的数据的字节数 flags:0 dest_addr:目的地址,服务器的地址 addrlen:sizeof(dest_addr) */ close() //2.未连接的udp socket //客户端 socket() sendto() recvfrom() close() //服务器 socket() bind() recvfrom() sendto() close()

    14、socket中的阻塞函数

    recv() 阻塞的 accept() 阻塞的 recvfrom() 阻塞的 listen() 是非阻塞的

    15、socket连接的方式

    写好socket程序后,有2种连接方法: 1)客户端和服务器统一使用127.0.0.1;这时候相当于是在一台电脑上运行客户端和服务器 2)客户端和服务器统一使用服务器在局域网的ip地址,比如192.168.16.153,这时候客户端和服务器运行在2台电脑上 socket通信也是进程间通信的一种方式,但是socket把进程通信从在同一台电脑,扩展到了可以在不同电脑之间通信
    转载请注明原文地址: https://ju.6miu.com/read-12784.html

    最新回复(0)