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&lname=%s&telnum=%s&email=%s");wsprintfA(buffer,fname, lname, telnum, email);
-- 解释你想在这里做什么。您使用strcat
和strcpy
使用字符数据设置缓冲区,然后通过调用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 不发送,显示连接失败的主要内容,如果未能解决你的问题,请参考以下文章