所以我想我会尝试使用HTTP,并尝试将简单的普通(未编码)文本从我的程序发送到服务器。但是,有些事情是不对的,我不知道是什么。
这是服务器端的PHP脚本,我已经通过从HTML表单发送POST数据进行了测试,它运行得很好,所以我猜服务器端没有任何问题。
<?php
$file = 'postData.txt';
$somecontent = $_POST['dat'];
$fp = fopen($file, 'w') or die('Could not open file!');
fwrite($fp, "$somecontent") or die('Could not write to file');
fclose($fp);
?>
这是程序(这段代码包括一些未使用的部分,比如在缓冲区中读取文件内容等等,这就是我一直在玩它并且每隔5秒更换一次东西,不介意):
#include <windows.h>
#include "WinSock2.h"
#include <stdio.h>
#include <stdint.h>
#include <iostream>
int main()
{
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return 0;
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd < 0) throw;
SOCKADDR_IN service;
service.sin_family = AF_INET;
service.sin_port = htons(80);
LPHOSTENT host = gethostbyname("123.17.25.123");
if (!host) throw;
service.sin_addr = *((LPIN_ADDR)*host->h_addr_list);
if (connect(fd, (SOCKADDR *)&service, sizeof(service)) < 0) throw;
FILE *f = fopen("file.txt", "rb");
if (!f) throw;
uint32_t len = 0;
fseek(f, 0x00, SEEK_END);
len = ftell(f);
fseek(f, 0x00, SEEK_SET);
char header[1024];
char *buffer = new char[len];
fread(buffer, sizeof(char), len, f);
sprintf(header,
"POST /recv.php HTTP/1.1\r\n"
"Host: 123.17.25.123\r\n"
"User-Agent: Mozilla Firefox/4.0\r\n"
"Content-Length: %d\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Accept-Charset: utf-8\r\n\r\n",
len+4);
std::cout << header << std::endl;
send(fd, header, strlen(header), 0);
send(fd, "dat=", 4, 0);
send(fd, buffer, strlen(buffer), 0);
send(fd, "\r\n", 2, 0);
delete [] buffer;
fprintf(stderr, "Done\n");
closesocket(fd);
WSACleanup();
return 0;
}
那么,它有什么问题?有谁有想法吗? :P
edit1:我使用wireshark监控流量并尝试运行该程序几次,但没有捕获数据包。奇怪的是,它甚至没有发送任何东西。
edit2:感谢TokenMacGuy让它发挥作用。上面的代码是蹩脚的,但它会读取所有文件内容并将其作为POST数据发送到您的服务器,希望它对像我这样的新手学习有用。再次感谢你!
答案 0 :(得分:1)
POST应该在数据之前有两个换行符,而不是在它之后。
"Accept-Charset: utf-8\r\n\r\n"
"dat=somedata\r\n",
答案 1 :(得分:1)
您没有收到数据,因为您实际上并未发送任何数据。虽然buffer
中出现sprintf
,但没有格式说明符可供使用(只有格式化长度)。
尝试完全从sprintf调用中删除buffer
,然后两次调用send
,一次调用标题(如您所做),然后再次发送实际数据。
或许您不打算从您阅读的文件中发送任何数据。你只想得到dat=somedatar
。问题是您将内容类型指定为text/plain
,在这种情况下,服务器根本不会解释它。内容类型可能应为application/x-www-form-urlencoded
。由于dat
参数是正文的一部分,因此content-length
标题必须包含它。如果内容长度与作为内容发送的实际字节数不匹配,符合要求的服务器将忽略整个请求(通常返回400-499范围的响应代码)。