一.网络命令
1.ping
ping命令用来检测网络是否连通,具体用法为:
ping + 任意网址
结果如下:
当出现上述字段时,证明网络是连通的,这里值得注意的是,ping命令执行之后会不断进行网络检测,不会停止,需要主动停止,但是我们也可以指定ping命令的检测次数,指令为:
ping -c + 次数 + 任意网址
如图,执行指定次数后便会立即退出。
2.netstat
netstat是一个用来查看网络状态的重要工具,常用的选项有以下几个:
- n:拒绝显示别名,能显示数字的全部转换为数字。
- l:仅列出有在Listen(监听)的服务状态。
- p:显示建立相关链接的程序名。
- t(tcp):仅显示tcp相关选项。
- u(udp):仅显示udp相关选项。
- a(all):显示所有选项,默认不显示LISTEN相关。
3.watch
watch命令可以定期执行某命令,具体用法为:
watch -n + 数字 + 命令
即每个若干数字时长就会执行一次后边的命令。
4.pidof
pidof指令可以直接通过进程的名字来查看该进程的pid,具体用法为:
pidof + 进程名
二.UDP网络编程
1.创建Socket
#include <sys/types.h>
#include <sys/socket.h>int socket(int domain, int type, int protocol);
该函数用于创建套接字。
- 参数1表示套接字的用途,一般可有两种选择:
AF_UNIX:本地
AF_INET:网络
- 参数2表示套接字的类型,在UDP使用中,设为SOCK_DGRAM,即面向数据报,在TCP中,则设为SOCK_STREAM,即面向字节流。
- 参数3表示协议的名称或编号,一般不做处理,设为0。
- 返回值为文件描述符,返回失败为-1。
2.bind
#include <sys/types.h>
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
该函数用于绑定端口号。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为绑定套接字的结构体信息。
- 参数3为结构体大小。
绑定成功返回0,绑定失败返回-1。
3.recvfrom
#include <sys/types.h>
#include <sys/socket.h>ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
该函数用于读取网络传输的数据。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为缓冲区。
- 参数3为缓冲区大小。
- 参数4为阻塞标记。
- 参数5表示信息的来源。
- 参数6为信息来源的大小。
读取成功返回数据大小,失败返回-1。
4.sendto
#include <sys/types.h>
#include <sys/socket.h>ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *src_addr, socklen_t addrlen);
该函数用于发送网络传输的数据。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为缓冲区。
- 参数3为缓冲区大小。
- 参数4为阻塞标记。
- 参数5表示信息的目的地。
- 参数6为信息目的地的大小。
读取成功返回数据大小,失败返回-1。
5.字节序转换
#include<arpa/inet.h>
uint32_t htonl(uint_32_t hostlong);
uint16_t htons(uint_16_t hostshort);
uint32_t ntohl(uint_32_t netlong);
uint16_t ntohs(uint_16_t netshort);
三.TCP网络编程
TCP的通信方式与UDP略有不同,在UDP中,两个进程通过创建套接字,并绑定之后,就可以互相进程通信,但是TCP不同,TCP处理进行UDP的基本操作之外,还需要建立套接字的连接,才能进行通信。
1.连接socket
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);
参数1:为套接字。
参数2:backlog + 1,表示全连接队列中,已经建立三次握手成功的连接的个数。
成功返回0,失败返回-1。
全连接队列,即当服务器压力很大,来不及获取新连接时,在TCP传输层由系统将新连接维护起来的队列,等待服务器来获取连接。
该函数可以将套接字设为可连接状态,从而去等待对方建立连接,进而实现通信。
2.accept
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
该函数用于接受套接字连接。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为绑定套接字的结构体信息。
- 参数3为结构体大小。
每次连接成功时,会返回一个新的文件描述符,失败返回-1。
3.connect
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
该函数用于连接套接字。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为绑定套接字的结构体信息。
- 参数3为结构体大小。
成功连接返回0,失败返回-1。
4.recv/send
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void* buf, size_t len, int flags);
ssize_t send(int sockfd, void* buf, size_t len, int flags);
两个函数分别用于TCP中读取/发送网络传输的数据。
- 参数1为绑定对应套接字的文件描述符。
- 参数2为缓冲区。
- 参数3为缓冲区大小。
- 参数4为阻塞标记。
因为TCP是面向字节流的网络传输协议,所以我们也可以使用read和write两个文件流操作函数来读取/发送网络传输的数据。
5.popen
#include <stdio.h>
FILE *popen(const char *command, const char *type);
该函数用于执行命令行指令,并将执行结果以管道文件的形式返回。
该函数在执行时,会创建一个管道文件,同时创建子进程,由子进程执行命令行指令,并将执行结果写入管道文件中,最后由父进程对管道文件进行读取等操作。
- 参数1为命令行指令字符串。
- 参数2为父进程对管道文件的执行方式,包括'r'/'w'/'a'。
6.TCP为何支持全双工
在TCP创建套接字时,每生成一个文件描述符fd,就代表有一个连接,建立连接之后,通信双方都会有两个缓冲区,分别为发送缓冲区和接收缓冲区。
read、write、send、recv等函数的本质都是进行数据在缓冲区之间的拷贝。
发送数据的本质,是从发送方的发送缓冲区把数据通过协议栈和网络拷贝到接收方的接收缓冲区。
数据被拷贝进TCP的发送缓冲区之后,这些数据如何什么时候发送,发送多少,发送失败等问题,都由TCP自己控制,而TCP位于传输层,传输层属于OS,所以这最终还是OS要做的事情,这就是TCP名为传输控制协议的原因。