【问题标题】:(GET HTTP Request) C++ sockets using winsock.h(GET HTTP 请求)使用 winsock.h 的 C++ 套接字
【发布时间】:2015-12-29 06:14:16
【问题描述】:

好的,在任何人下结论之前(并确保我与其他人保持相关的事实),基本上,我正在尝试做一个 使用 Winsock.h 在 C/C++ 中使用套接字获取请求
[SocketRequest函数运行存在的主要问题]
我从以下任何地方收到错误响应代码: “WSAENOTCONN 10057”到“WSAENOTSOCK 10038” 其中,我在这里找到了更多信息:https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx

现在,这对其他人来说有点无关紧要,但更多的是我的情况。 我正在尝试使用“winsockx.h”在 XBOX360 Devkit 上实现这一点,当我发出“SocketRequest”时它崩溃了......这是用于调试目的的代码 WITH 输出。 (我知道这不是您通常会看到的,所以随心所欲)

这是包含的文件:

#include "stdafx.h"
#include <time.h>
#include "Hooks.h"
#include <xhttp.h>
#include <winsockx.h>
#include <iostream>
#include <xtl.h>
#include <xbdm.h>
#include <malloc.h>
#include <stdio.h>

以下是定义和实例:

int Socket;
struct sockaddr_in SocketAddress;
char bufferReturn[10000];
char serverAddr[2000];
bool returnTEST = false;
char *Request1;
char *Request2;
char *ResetRequest;
//http://www.cplusplus.com/forum/general/9403/
//http://www.cplusplus.com/forum/beginner/139313/

#define SERVER_PORT htons(80)

代码如下(包括无法运行的SocketRequest函数):

char* SocketRequest(char* URL, char* Path = "")
{
//THIS IS THE FUNCTION THAT CRASHES WHEN IT'S CALLED IDK WHY... NOTHING IN HERE RUNS, NOT EVEN THE "prinf" STATEMENT. 
    printf( "Step 0");
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSA Startup FAILED! ", WSAGetLastError() );
    }
    printf( "Step 1");
    SocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    printf( "Step 2");
    SocketAddress.sin_family = AF_INET;
    printf( "Step 3");
    SocketAddress.sin_port = SERVER_PORT;
    printf( "Step 4");
    Socket = socket(AF_INET, SOCK_STREAM, 0);

    printf( "Step 5");
    // Make sure we have a valid socket
    if( Socket == INVALID_SOCKET )
    {
        printf( "Attempted to send to an invalid socket.\n" );
    }
    printf( "Step 6");
    // If we're not broadcasting, make sure we have a peer to send to
    if( SocketAddress.sin_addr.s_addr == INADDR_NONE )
    {
        printf( "Attempted to send a non-broadcast when we have no peer.\n" );
    }
    printf( "Step 7");
    if( bind( Socket, ( const sockaddr* )&SocketAddress, sizeof( SocketAddress ) ) != 0 )
    {
        printf( "Failed to bind socket, error %d.\n", WSAGetLastError() );
    }

    printf( "Step 8");
    strcpy(serverAddr, "GET /");
    if (strlen(Path) > 0){
        strcat(serverAddr, Path);
    }
    printf( "Step 9");
    strcat(serverAddr, "");
    strcat(serverAddr, " HTTP/1.0\r\nHOST: ");
    strcat(serverAddr, URL);
    strcat(serverAddr, "\r\n\r\n");

    printf( "Step 10");
    char buffer[10000];
    int nDataLength;
    while ((nDataLength = recv(Socket, buffer, 10000, 0)) > 0){
        int i = 0;
        while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
            cout << buffer[i];
            i += 1;
            printf("While_Loop1_Fail");
        }
        printf("While_Loop2_Fail");
    }
    closesocket(Socket);
    return 0;
    WSACleanup();
}

void ResetArray(char *array_)
{
    char *begin = bufferReturn;
    char *end = begin + sizeof(array_);
    std::fill(begin, end, 0);
}

bool IsRequest()
{
//HERES WHERE IT CRASHES, AS **SOON** as the "Request1 = SocketRequest" line is called.
    printf("is_request...");
    Request1 = SocketRequest("www.mywebsite.com", "test/test.php"); 
    if (strstr(Request1, "ON"))
    {
        returnTEST = true;
        ResetArray(bufferReturn);
        return true;
    }
    else if (strstr(Request1, "OFF"))
    {
        returnTEST = false;
        ResetArray(bufferReturn);
        return true;
    }
    else if (strstr(Request1, "Null"))
    {
        printf(strstr(bufferReturn, "Null\n\n"));
        return false;
    }
}

bool Reset()
{
    ResetRequest = SocketRequest("www.mywebsite.com", "test/test.php");
    printf(ResetRequest);
    return true;
}
//This is where the code is ran from on the Console ON BOOT.
void mainThread(){
    for(;;Sleep(45)){
            if(bInitialized[0] == true || bInitialized[1] == true)
            {
//THIS IS WHERE the function "IsRequest" is called.
                printf("binit is true!");
                if (IsRequest())
                {
                    printf("Worked!\n");
                }
            }
        }
    }

这是运行时的输出:

binit is true! and still running...is_request...
    ------------------------------------------------------------------------
      stop code: 0x2b (PANIC_STACK_SWITCH)
        (0x3A097900,0x80072908,0x3A14E110,0x80076D88)
    ------------------------------------------------------------------------
    Call Stack:
        0x80072908 (EADDR)
        0x80076D88 (LR)
        0x91F96F3C
        0x91F86B64
        0x91F75520
        0x91F5E92C
        0x91F5EC68
        0x91F5EECC
        0x91F682E8

停止代码:0x2b (PANIC_STACK_SWITCH) = 当内核模式驱动程序使用太多堆栈空间时,通常会出现此错误。当内核中发生严重的数据损坏时,它也会出现。 参考:https://msdn.microsoft.com/en-us/library/windows/hardware/ff557460(v=vs.85).aspx


差不多了,我不明白为什么它没有运行我的功能,我不明白它为什么会崩溃。如果有人有任何想法,将不胜感激;因为,我知道这是一个相当压倒性的信息主题,可能只与我的情况有关。 [我可以假设堆栈重载或 char* 类型的转换无效?]
谢谢。

【问题讨论】:

  • 你还没有打电话给connect
  • @Ben 这就是 "if( bind( Socket"... 行在 SocketRequest 函数中所做的。而且,SocketRequest 函数甚至不会运行,就像它甚至不会 printf 一样。编辑*我纠正自己,你是对的,但仍然没有解决问题....
  • 那是因为其他的都是错误的...你应该从一个示例代码重新开始。
  • @Ben 好的,我已经一遍又一遍地开始了。这是在外部系统上运行的,调试有点困难(当然我可以从我的计算机上完成),编码会有所不同。至于其他都错了,你怎么看?
  • 是否有任何理由使用套接字来执行 HTTP 请求而不是高级库(例如,WinHTTP 或 WinINet)?

标签: c++ c sockets winsock xbox360


【解决方案1】:

你还没有打电话给connect

当然connect 需要一个远程地址,但你只有一个名字。所以你需要通过调用gethostbyname将名字转换成地址。

一旦你有了地址,顺序是:

  • socket 创建一个套接字对象。
  • bind 将连接的本地端绑定到本地地址和端口。 Bind 连接 您的端 套接字。
  • connect 将流套接字连接到远程主机。

您不需要在这里使用hton* 系列函数。它们用于转换您通过网络收到的号码。

备注:看起来对socketbind 的调用当然应该合并,不是吗?它们不存在的原因是历史性的 - 这就是它现在的运作方式。

【讨论】:

  • 感谢您的回答/帮助...但是,我不能使用“gethostbyname”,因为它已从我正在使用的“winsockx.h”库中弃用(来源中说: ): gethostbyname() 和 gethostbyaddr() 的错误返回码 *(使用解析器时)。请注意,这些错误 * 通过 WSAGetLastError() 检索,因此必须遵循 * 避免与来自 * 特定实现或语言运行时系统的错误编号冲突的规则。 * 因此,代码基于 WSABASEERR+1001。 * 另请注意,[WSA]NO_ADDRESS 仅出于*兼容性目的而定义。
  • 这里是 winsockx.h 的来源:pastebin.com/CApdcw6y 还有其他方法可以获取主机名吗?
猜你喜欢
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多