Error_016 2023-12-16 13:13 采纳率: 27.3%
浏览 10

关于winsock2 udp通信问题

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
 
  • 写回答

1条回答 默认 最新

  • _君莫笑 2023-12-16 15:53
    关注

    img

    img

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 12月16日

悬赏问题

  • ¥15 python怎么在已有视频文件后添加新帧
  • ¥20 虚幻UE引擎如何让多个同一个蓝图的NPC执行一样的动画,
  • ¥15 fluent里模拟降膜反应的UDF编写
  • ¥15 MYSQL 多表拼接link
  • ¥15 关于某款2.13寸墨水屏的问题
  • ¥15 obsidian的中文层级自动编号
  • ¥15 同一个网口一个电脑连接有网,另一个电脑连接没网
  • ¥15 神经网络模型一直不能上GPU
  • ¥15 pyqt怎么把滑块和输入框相互绑定,求解决!
  • ¥20 wpf datagrid单元闪烁效果失灵