udp_client.cpp:
#include<iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <string>
#include "udpep.h"
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int run_cmd(string cmd,string &buf);
int Resident_connect(sockaddr_in sender_addr,int port);
//执行cmd指令
int run_cmd(string cmd,string &buf){
char MsgBuff[1024];
int MsgLen = 1020;
FILE * fp;
if(cmd.data() == NULL)
{
return -1;
}
if((fp = _popen(cmd.data(),"r")) == NULL){
return -2;
}else{
memset(MsgBuff,0,MsgLen);
while(fgets(MsgBuff,MsgLen,fp) != NULL){
buf += MsgBuff;
}
if(_pclose(fp) == -1){
return -3;
}
}
return -4;
}
//常驻连接函数
int Resident_connect(sockaddr_in sender_addr,int port){
int Result;
//创建常驻tcp套接字
SOCKET Resident_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (Resident_socket == INVALID_SOCKET) {
printf("socket establish failed\n");
system("pause");
WSACleanup();
return -1;
}
//创建标准IPv4地址
// sockaddr_in addr;
// memset(&addr,0,sizeof(addr));
// addr.sin_family = AF_INET;
// addr.sin_port = port;
// addr.sin_addr.s_addr = sender_addr.sin_addr.s_addr;
//回应常驻连接
connect(Resident_socket,(sockaddr*)&sender_addr,sizeof(sender_addr));
//开始接收命令
while(true){
string message;
// memset(message,0,sizeof(message));
do{
char buf[1024];
memset(buf,0,sizeof(buf));
Result = recv(Resident_socket,buf,sizeof(buf),0);
message += buf;
}while(Result);
cout << inet_ntoa(sender_addr.sin_addr) << "::" << port << " >" << message << endl;
//执行命令
//执行cmd命令
string return_cmd_message;
run_cmd(message,return_cmd_message);
send(Resident_socket,return_cmd_message.data(),sizeof(return_cmd_message),0);
}
}
int main(){
//初始化
int Result;
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
printf("WSAStartup failed\n");
system("pause");
return -1;
}
//创建udp套接字
SOCKET Host = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //UDP
if (Host == INVALID_SOCKET) {
printf("socket establish failed\n");
system("pause");
WSACleanup();
return -1;
}
//创建标准IPv4地址
sockaddr_in addrServ;
memset(&addrServ,0,sizeof(addrServ));
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(SERVER_PORT);
addrServ.sin_addr.s_addr = INADDR_ANY;
//绑定套接字
bind(Host, (sockaddr*)&addrServ, sizeof(addrServ));
//创建组播地址
ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP);
mreq.imr_interface.s_addr = INADDR_ANY;
//加入广播组
setsockopt(Host,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mreq,sizeof(mreq));
//发送待机信号
while(true){
//创建空发送者地址
sockaddr_in sender_addr;
int addr_size = sizeof(sender_addr);
Result = sendto(Host,(char)SANDBY,sizeof(int),0,(sockaddr*)&addrServ,sizeof(addrServ));
if (Result == SOCKET_ERROR) {
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
system("pause");
closesocket(Host);
WSACleanup();
return 1;
}
//接收常驻连接请求
char buf[1024];
Result = recvfrom(Host,buf,sizeof(buf),0,(sockaddr*)&sender_addr,&addr_size);
if(buf[0] == (char)CONNECT){
string message = buf;
int resident_port = atoi(message.substr(2,message.length()).data());
Resident_connect(sender_addr,resident_port);
}
// if (Result == SOCKET_ERROR) {
// wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
// closesocket(sHost);
// WSACleanup();
// return 1;
// }
}
//关闭套接字
Result = closesocket(Host);
if (Result == SOCKET_ERROR) {
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
system("pause");
WSACleanup();
return 1;
}
WSACleanup();
return 0;
}
输出内容:
sendto failed with error: 10014
udp_server.cpp
#include<iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <udpep.h>
#include <regex>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
int getRand(int min, int max);
int find_client(SOCKET &Server);
int Resident_connect(const char* host,int port,SOCKET &Server);
//int enter_user_command(&SOCKET Server);
int enter_user_command(SOCKET &Server){
while(true){
//接收用户命令
string usermess;
cin >> usermess;
//命令处理
//连接命令
if(regex_match(usermess,regex("连接"))){
//提取IP地址
string client_resident_connect_ip = regex_replace(usermess, regex("连接 "), "");
//随机常驻端口号
int resident_port = getRand(1024,49151);
// cout << usermess << "::" << resident_port << endl;
//发起常驻连接
Resident_connect(client_resident_connect_ip.data(),resident_port,Server);
}else if(usermess == "扫描网络"){
find_client(Server);
}
}
}
//生成随机数
int getRand(int min, int max) {
return ( rand() % (max - min + 1) ) + min ;
}
//寻找可用连接函数
int find_client(SOCKET &Server){
//创建空发送者地址
sockaddr_in sender_addr;
int addr_size = sizeof(sender_addr);
//设置超时时间
timeval tv = {2, 0};
setsockopt(Server, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(timeval));
//接收客户端待机信号
for(int i = 0;i < 10;i++){
//创建缓存变量
char buf[1024];
if(recvfrom(Server,buf,sizeof(buf),0,(sockaddr*)&sender_addr,&addr_size) <= 0){
cout << "recvfrom failed, the error code = %d"<< WSAGetLastError() << endl;
break;
}else{
cout << sender_addr.sin_addr.S_un.S_addr << endl;
}
}
}
//常驻连接函数
int Resident_connect(const char* host,int port,SOCKET &Server){
//发送连接请求: 状态码 CONNECT + 常驻端口号
//创建回应地址
// sockaddr_in sender_addr;
// sender_addr.sin_family = AF_INET;
// sender_addr.sin_port = htons(SERVER_PORT);
// sender_addr.sin_addr.s_addr = htons(host);
//创建标准IPv4地址
sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = inet_addr(host);
int addr_len = sizeof(addr);
string connect_request_message = to_string(CONNECT) + to_string(port);
sendto(Server,connect_request_message.data(),sizeof(connect_request_message.data()),0,(sockaddr*)&addr,addr_len);
int Result;
//创建常驻tcp套接字
SOCKET Resident_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (Resident_socket == INVALID_SOCKET) {
printf("socket establish failed\n");
WSACleanup();
return -1;
}
//监听连接
listen(Resident_socket,5);
//接收客户端请求
SOCKET client_socket = accept(Resident_socket,(sockaddr*)&addr,&addr_len);
//开始发送命令
while(true){
string send_message;
cin >> send_message;
send(Resident_socket,send_message.data(),sizeof(send_message),0);
string return_message;
// memset(message,0,sizeof(message));
do{
char buf[1024];
memset(buf,0,sizeof(buf));
Result = recv(Resident_socket,buf,sizeof(buf),0);
return_message += buf;
}while(Result);
cout << host << "::" << port << " >" << return_message << endl;
}
}
int main(){
//初始化
srand((unsigned)time(NULL));
WSADATA wsaData;
int Result;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
//创建服务器套接字
SOCKET Server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //采用UDP
if (Server == INVALID_SOCKET) {
printf("socket establish failed\n");
return -1;
}
//创建格式化的IPv4地址
sockaddr_in addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(SERVER_PORT); //相同的端口响应相同端口的请求
addrServ.sin_addr.S_un.S_addr = htons(INADDR_ANY);
//绑定地套接字
bind(Server, (const sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
//创建组播地址
ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(GROUP_IP);
mreq.imr_interface.s_addr = INADDR_ANY;
//加入广播组
setsockopt(Server,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mreq,sizeof(mreq));
//用户输入命令
enter_user_command(Server);
//回应待机信号
// sendto(Server,buf,sizeof(buf),0,(sockaddr*)&sender_addr,&addr_size);
//
// if (retVal == SOCKET_ERROR) {
// printf("bind failed\n");
// closesocket(Server);
// WSACleanup();
// return -1;
// }
return 0;
}
输出内容:
扫描网络
recvfrom failed, the error code = %d10060
udpep.h
#ifndef UDPEP_H
#define UDPEP_H
#define SERVER_PORT 2417
#define GROUP_IP "224.1.1.4"
#define SANDBY 0
#define CONNECT 1
#endif