【问题标题】:Winsock Doesnt Send , Shows Connection FailureWinsock 不发送,显示连接失败
【发布时间】:2016-04-10 16:35:17
【问题描述】:

我试图让这段代码将数据发送到一个 php 文件,而不是发送,它只是直截了当地返回连接失败,不清楚原因,但对我来说一切都很好

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Winsock.h>

#pragma comment (lib, "ws2_32")

int main()
{
    char fname[32];
    printf("Enter Your name: \n");
    scanf("%31s",fname);

    char lname[32];
    printf("Enter Your Last name: \n");
    scanf("%31s",lname);

    char telnum[32];
    printf("Enter Your Tel Number: \n");
    scanf("%31s",telnum);

    char email[32];
    printf("Enter Your Email: \n");
    scanf("%31s",email);

    //Initiate Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2,2),&wsaData);

    SOCKET m_socket;
      if(m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) ==INVALID_SOCKET)
        {
            printf("Invalid Socket :WSAGetLastError()");
        }
        sockaddr_in clientService;
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
    clientService.sin_port = htons(80);
    LPHOSTENT host = gethostbyname("127.0.0.1");

    if(connect(m_socket,(SOCKADDR*)&clientService,sizeof(clientService))==SOCKET_ERROR)
        {
        printf("Connection Failure");
        WSACleanup();
        return 1;
        }

    char buffer[1024];

    strcpy(buffer,"POST /server/dbarea.php HTTP/1.1\n");
    strcat(buffer,"Content - Type:application/x-www-form-urlencoded\n");
    strcat(buffer,"Host: localhost\n");
    strcat(buffer,"content-Length: 32\n");
    strcat(buffer,"\n");
    strcat(buffer,"fname=%s&lname=%s&telnum=%s&email=%s");
    wsprintfA(buffer,fname, lname, telnum, email);
    if(!send(m_socket, buffer, strlen(buffer), 0))
    {
        printf("Not Sent ! Error : %d", GetLastError());
    }
    else{
        MessageBoxA(NULL, "Message Sent", "", MB_OK);
    }
    return 0;
}

而php看起来是这样的

<?php
  $fname = $_POST['fname'];
  $lname = $_POST['lname'];
  $telnum = $_POST['telnum'];
  $email = $_POST['email'];

  $log = "Data : \n First Name: $fname\n Last Name: $lname\n Telephone :  $telnum\n Email : $email";
  $file =  fopen("datas.txt","w");
  fwrite($file, $log);
  fclose($file);
?>

【问题讨论】:

  • 您可能被 Windows 防火墙阻止。你能telnet到你的服务器吗?还有WSAGetLastError返回的是什么?
  • strcat(buffer,"fname=%s&amp;lname=%s&amp;telnum=%s&amp;email=%s");wsprintfA(buffer,fname, lname, telnum, email); -- 解释你想在这里做什么。您使用strcatstrcpy 使用字符数据设置缓冲区,然后通过调用wsprintfA 放弃所有这些工作。此外,格式字符串fname 的参数比您指定的要多,因此行为未定义。
  • printf("Connection Failure"); 替换为printf("Connection Failure. Error code: %d", WSAGetLastError());,然后查看connect() documentation 找出导致错误的原因。
  • @PaulMcKenzie 代码尝试使用strcpy/strcat 创建格式字符串,然后将其传递给wsprintfA 以创建最终的HTTP 请求。但是代码错误地使用了wsprintfA。此外,使用if (!send(...)) 检查send 的错误是错误的,应该改为if (send(...) == SOCKET_ERROR)

标签: c++ winsock


【解决方案1】:

这段代码有几个错误,分别是HTTP请求格式错误、wsprintfA()的误用、send()的错误处理。

试试类似的方法:

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Winsock.h>

#pragma comment (lib, "ws2_32")

int main()
{
    char fname[32];
    printf("Enter Your name: \n");
    scanf("%31s", fname);

    char lname[32];
    printf("Enter Your Last name: \n");
    scanf("%31s", lname);

    char telnum[32];
    printf("Enter Your Tel Number: \n");
    scanf("%31s", telnum);

    char email[32];
    printf("Enter Your Email: \n");
    scanf("%31s", email);

    //Initiate Winsock
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0)
    {
        printf("WinSock failed: %d", iResult);
        return 1;
    }

    SOCKET m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_socket == INVALID_SOCKET)
    {
        printf("Invalid Socket: %d", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    sockaddr_in clientService;
    memset(&clientService, 0, sizeof(clientService));
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
    clientService.sin_port = htons(80);

    if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
    {
        printf("Connection Failure: %d", WSAGetLastError());
        closesocket(m_socket);
        WSACleanup();
        return 1;
    }

    char data[256];
    sprintf(data, "fname=%s&lname=%s&telnum=%s&email=%s", fname, lname, telnum, email);

    char buffer[1024];
    strcpy(buffer, "POST /server/dbarea.php HTTP/1.1\r\n");
    strcat(buffer, "Content-Type: application/x-www-form-urlencoded\r\n");
    strcat(buffer, "Host: localhost\r\n");
    sprintf(&buffer[strlen(buffer)], "Content-Length: %d\r\n", strlen(data));
    strcat(buffer, "\r\n");
    strcat(buffer, data);

    if (send(m_socket, buffer, strlen(buffer), 0) == SOCKET_ERROR)
    {
        printf("Not Sent ! Error : %d", WSAGetLastError());
        closesocket(m_socket);
        WSACleanup();
        return 1;
    }

    closesocket(m_socket);
    WSACleanup();

    MessageBoxA(NULL, "Message Sent", "", MB_OK);

    return 0;
}

话虽如此,既然您使用的是 C++,那么您应该使用 std::string 和相关功能,而不是诉诸 C 功能。

#include "stdafx.h"
#include <windows.h>
#include <Winsock.h>
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>

#pragma comment (lib, "ws2_32")

void error(const char *what, int errCode)
{
    std::ostringstream oss;
    oss << what << "! Error: " << errCode;
    throw std::runtime_error(oss.str());
}

struct sWsa
{
    sWsa()
    {
        WSADATA wsaData;
        int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != 0)
            error("WinSock failed", iResult);
    }

    ~sWsa()
    {
        WSACleanup();
    }
};

struct sSocket
{
    SOCKET m_Socket;

    sSocket(SOCKET s) : m_Socket(s) {}
    ~sSocket()
    {
        if (m_Socket != INVALID_SOCKET)
            closesocket(m_Socket);
    }

    operator SOCKET() { return m_Socket; }
    bool operator !() { return (m_Socket == INVALID_SOCKET); }
};

int main()
{
    try
    {
        std::string fname;
        std::cout << "Enter Your name: ";
        std::getline(std::cin, fname);

        std::string lname;
        std::cout << "Enter Your Last name: ";
        std::getline(std::cin, lname);

        std::string telnum;
        std::cout << "Enter Your Tel Number: ";
        std::getline(std::cin, telnum);

        std::string email;
        std::cout << "Enter Your Email: ";
        std::getline(std::cin, email);

        sWsa wsa;

        sSocket sckt = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
        if (!sckt)
           error("Invalid Socket", WSAGetLastError());

        sockaddr_in clientService = {0};
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
        clientService.sin_port = htons(80);

        if (connect(sckt, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
            error("Connection Failure", WSAGetLastError());

        std::ostringstream oss_data;
        oss_data << "fname=" << fname
            << "&lname=" << lname
            << "&telnum=" << telnum
            << "&email=" << email;
        std::string data = oss_data.str();

        std::ostringstream oss_request;
        oss_request << "POST /server/dbarea.php HTTP/1.1\r\n"
            << "Content-Type: application/x-www-form-urlencoded\r\n"
            << "Host: localhost\r\n"
            << "Content-Length: " << data.size() << "\r\n"
            << "\r\n"
            << data;
        std::string request = oss_request.str();

        if (send(sckt, request.c_str(), request.size(), 0) == SOCKET_ERROR)
            error("Not Sent", WSAGetLastError());
    }
    catch (const std::exception &e)
    {
        std::cerr << e.what();
        return 1;
    }

    MessageBoxA(NULL, "Message Sent", "", MB_OK);

    return 0;
}

【讨论】:

  • strcat(buffer, "Content-Length: %d\r\n", strlen(data));在函数调用中返回错误太多争论。
  • @Manheim 我修正了这个例子。
  • 这里的问题可能来自 php.ini。我尝试过的所有内容都不会将数据发布到文本文件中。这是代码pastebin.com/YnArUVDZ
  • @Manheim 您已经在问题中展示了 PHP 代码。看起来不错。您还没有说出 connect() 实际失败的错误代码,就像 ub3rst4r 建议的那样。当这段代码运行时,PHP 是否真的在本地 PC 上运行并监听 80 端口?我猜不是。
  • 现在它不再显示错误了。它现在正确显示 MessageBox :) 但它仍然不发送 textFile ,我仍然想知道可能出了什么问题。它不会将数据发送到文本文件。
猜你喜欢
  • 2011-05-14
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多