用来检测网络连通性的。
比如ping 百度的官网
ping www.bai.com
这个指令执行后默认是不会停下来的,我们可以加入 -c + 数字选项,表示要ping几次
比如ping两次
ping -c2 www.bai.com
查看所有的网络连接活动
netstat -a
查看当前会话UDP的网络活动
netstat -u
查看所有会话的UDP的网络活动
netstat -au
查看TCP的
netstat -t
查看所有会话的同理
往后面再加一个p选项,可以查看到这个程序的PID和进程名字
netstat -atp
我们发现再PID那里有很多是空的,空的就说明这是系统启动的,或者是其他用户启动的网络进程,我们作为普通用户是看不到的。用root身份就可以看到了。
另外在主机那里可以看到很多的 localhost,我们可以再加上n选项,把这些转化成为数字
netstat -atpn
这样就可以看到localhost被转为成为了 127.0.0.1 。
netstat -tl
会把只处于监听状态的tcp进程显示出来
可以周期性的执行某一个linux指令
watch -n 1 ls
-n 后面接数字,表示每个多少秒执行一次,后面接要执行的指令
这个指令配合netstat可以监控当前网络进程的信息,很好用。
pidof + 网络进程名
执行这个指令,就可以直接返回该网络进程的PID。
适用于服务器在后台运行时,我们想通过kill 命令来杀掉服务器时,为了得到服务器的PID比较繁琐的问题,直接用该指令获得PID很方便快捷。
甚至可以直接结合管道,直接杀掉服务器
pidof 进程名 | xargs kill -9
其中 xargs的作用是将管道中的内容,转化到后续命令的命令行参数中,因为通过kill命令杀掉进程,是需要将该进程的PID通过命令行参数传入给kill程序的。
管道也是一个文件。
因为大部分的客户端都是在Windows上的,所以这里也就重点看下一下在Windows下,编写客户端有和不同
client.cc
#include #include #include #include #include #include #include #pragma warning(disable : 4996) #pragma comment(lib, "ws2_32.lib") std::string serverip = ""; // 填写你的云服务器ip uint16_t serverport = 8888; // 填写你的云服务开放的端口号 int main() { WSADATA wsd; WSAStartup(MAKEWORD(2, 2), &wsd); struct sockaddr_in server; memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(serverport); //? server.sin_addr.s_addr = inet_addr(serverip.c_str()); SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == SOCKET_ERROR) { std::cout << "sockererror" << std::endl; return 1; } std::string message; char buffer[1024]; while (true) { std::cout << "PleaseEnter@"; std::getline(std::cin, message); if (message.empty()) continue; sendto(sockfd, message.c_str(), (int)message.size(), 0, (struct sockaddr*)&server, sizeof(server)); struct sockaddr_in temp; int len = sizeof(temp); int s = recvfrom(sockfd, buffer, 1023, 0, (struct sockaddr*)&temp, &len); if (s > 0) { buffer[s] = 0; std::cout << buffer << std::endl; } } closesocket(sockfd); WSACleanup(); return 0; }
#include #include
与linux不同的是要包含这两个头文件
#pragma comment(lib, "ws2_32.lib")
开头这里是声明了一个库。
WSADATA wsd; WSAStartup(MAKEWORD(2, 2), &wsd);
WSADATA
是一个结构体类型,它包含了Winsock版本信息和状态信息。这个结构体通常在调用 WSAStartup
函数时由该函数填充。wsd
是 WSADATA
类型的一个变量,用于存储 WSAStartup
函数返回的信息。这些信息包括Winsock DLL的版本信息,以及用于后续Winsock调用(如 socket
、bind
、listen
、accept
等)的句柄或标识符。WSAStartup
是Winsock API的一个函数,用于初始化Winsock DLL。在应用程序调用任何Winsock函数之前,必须先调用 WSAStartup
。MAKEWORD(2, 2)
是一个宏调用,用于生成一个表示Winsock版本号的单词(WORD)。这里,2, 2
分别代表Winsock的主版本号和次版本号,即Winsock 2.2。Winsock 2.2是Winsock 2的一个版本,提供了更丰富的网络编程接口和更好的性能。&wsd
是 wsd
变量的地址,即指向 WSADATA
结构体的指针。WSAStartup
函数使用这个指针来填充 WSADATA
结构体,以返回关于Winsock DLL版本和状态的信息。
然后中间其他的地方就和linux上大差不差了,然后在结尾这里关闭之前打开的套接字
closesocket(sockfd); WSACleanup();
WinSock2.h是WindowsSocketsAPI(应用程序接口)的头文件,用于在 Windows平台上进行网络编程。它包含了WindowsSockets2(Winsock2)所需 的数据类型、函数声明和结构定义,使得开发者能够创建和使用套接字 (sockets)进行网络通信。 在编写使用Winsock2的程序时,需要在源文件中包含WinSock2.h头文件。这 样,编译器就能够识别并理解Winsock2中定义的数据类型和函数,从而能够正确 地编译和链接网络相关的代码。 此外,与WinSock2.h头文件相对应的是ws2_32.lib库文件。在链接阶段,需要 将这个库文件链接到程序中,以确保运行时能够找到并调用Winsock2API中实现 的函数。 在WinSock2.h中定义了一些重要的数据类型和函数,如: WSADATA:保存初始化Winsock库时返回的信息。
WSAStartup函数是WindowsSocketsAPI的初始化函数,它用于初始化 Winsock库。该函数在应用程序或DLL调用任何Windows套接字函数之前必须首 先执行,它扮演着初始化的角色。 以下是WSAStartup函数的一些关键点: 它接受两个参数:wVersionRequested和lpWSAData。
wVersionRequested用于 指定所请求的Winsock版本,通常使用MAKEWORD(major,minor)宏,其中 major和minor分别表示请求的主版本号和次版本号。lpWSAData是一个指向 WSADATA结构的指针,用于接收初始化信息。 如果函数调用成功,它会返回0;否则,返回错误代码。
WSAStartup函数的主要作用是向操作系统说明我们将使用哪个版本的Winsock 库,从而使得该库文件能与当前的操作系统协同工作。成功调用该函数后, Winsock库的状态会被初始化,应用程序就可以使用Winsock提供的一系列套接字 服务,如地址家族识别、地址转换、名字查询和连接控制等。这些服务使得应用程 序可以与底层的网络协议栈进行交互,实现网络通信。 在调用WSAStartup函数后,如果应用程序完成了对请求的Socket库的使用,应 调用WSACleanup函数来解除与Socket库的绑定并释放所占用的系统资源。
其实跟UDP没什么区别了
#include #include #include #pragma warning(disable : 4996) #pragma comment(lib, "ws2_32.lib") std::string serverip = ""; // 填写你的云服务器ip uint16_t serverport = 8888; // 填写你的云服务开放的端口号 int main() { WSADATA wsaData; int result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { std::cerr << "WSAStartupfailed:" << result << std::endl; return 1; } SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (clientSocket == INVALID_SOCKET) { std::cerr << "socketfailed" << std::endl; WSACleanup(); return 1; } sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(serverport); serverAddr.sin_addr.s_addr = inet_addr(serverip.c_str()); result = connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)); if (result == SOCKET_ERROR) { std::cerr << "connect failed" << std::endl; closesocket(clientSocket); WSACleanup(); return 1; } while (true) { std::string message; std::cout << "Please Enter@ "; std::getline(std::cin, message); if (message.empty()) continue; send(clientSocket, message.c_str(), message.size(), 0); char buffer[1024] = { 0 }; int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0); if (bytesReceived > 0) { buffer[bytesReceived] = '\0'; // 确保字符串以 null 结尾 std::cout << "Received from server: " << buffer << std::endl; } else { std::cerr << "recv failed" << std::endl; } } closesocket(clientSocket); WSACleanup(); return 0; }