网络指令
ping命令
用来检测网络连通性的。
比如ping 百度的官网
ping www.bai.com
这个指令执行后默认是不会停下来的,我们可以加入 -c + 数字选项,表示要ping几次
比如ping两次
ping -c2 www.bai.com
netstat
查看所有的网络连接活动
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进程显示出来
watch指令
可以周期性的执行某一个linux指令
watch -n 1 ls
-n 后面接数字,表示每个多少秒执行一次,后面接要执行的指令
这个指令配合netstat可以监控当前网络进程的信息,很好用。
pidof
pidof + 网络进程名
执行这个指令,就可以直接返回该网络进程的PID。
适用于服务器在后台运行时,我们想通过kill 命令来杀掉服务器时,为了得到服务器的PID比较繁琐的问题,直接用该指令获得PID很方便快捷。
甚至可以直接结合管道,直接杀掉服务器
pidof 进程名 | xargs kill -9
其中 xargs的作用是将管道中的内容,转化到后续命令的命令行参数中,因为通过kill命令杀掉进程,是需要将该进程的PID通过命令行参数传入给kill程序的。
管道也是一个文件。
Windows作为UDP客户端访问linux的DUP服务器
因为大部分的客户端都是在Windows上的,所以这里也就重点看下一下在Windows下,编写客户端有和不同
client.cc
#include <iostream>
#include <cstdio>
#include <thread>
#include <string>
#include <cstdlib>
#include <WinSock2.h>
#include <Windows.h>
#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 <WinSock2.h>
#include <Windows.h>
与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库的绑定并释放所占用的系统资源。
WindowsTCP客户端的访问
其实跟UDP没什么区别了
#include <winsock2.h>
#include <iostream>
#include <string>
#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;
}