Winsock 不发送,显示连接失败

Posted

技术标签:

【中文标题】Winsock 不发送,显示连接失败【英文标题】:Winsock Doesnt Send , Shows Connection Failure 【发布时间】: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) 【参考方案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 ,我仍然想知道可能出了什么问题。它不会将数据发送到文本文件。

以上是关于Winsock 不发送,显示连接失败的主要内容,如果未能解决你的问题,请参考以下文章

FLASHFXP提示连接失败

用FlashFXP时总是连接失败(连接丢失)原因是啥

SMTP 连接()失败。发送认证邮件时

为啥手机登录QQ邮箱总是显示连接服务器失败?

通过 *** 连接失败

我的FlashFXP连接失败(连接超时)怎样解决