Sending POST data using winsock (and receiving them with PHP server side script)
So I thought I would play with HTTP a bit and try to send simple plain(not encoded) text from my program to a server. However, something is not right and I don't know what.
Here is the server side PHP script, I have tested it by sending POST data from HTML form and it worked just great, so I guess there isn't anything wrong on server side.
<?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);
?>
Here is the program(this code includes some unused parts like reading file content in buffer etc., that's cuz I am playing with it all the time and changing stuff every 5 seconds, don't mind it):
#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;
}
So, what's wrong with it? Does anyone have any idea? :P
edit1: I monitored the traffic with wireshark and tried to run the program few times开发者_JAVA百科, but no packets were captured. Strange, it does not even send anything anywhere.
edit2: Thanks to TokenMacGuy got it working. Code above is lame, but it will read all file content and send it as POST data to your server, hopefully it will be useful for noobs like me to learn. Thank you once again!
You aren't recieving the data because you aren't actually sending any data. Although buffer
appears in the sprintf
, there's no format specifier to consume it (only the length is formatted).
Try removing the buffer
from the sprintf call altogether, and then call send
twice, once for the headers (as you already do) and again to send the actual data.
Or maybe you don't intend to send any data from the file you read. You just want to get that dat=somedatar
. The problem is that you indicate the content-type as text/plain
, in which case the server won't interpret it at all. The content type should probably be application/x-www-form-urlencoded
. Since the dat
parameter is part of the body, the content-length
header must include it. If the content length doesn't match the actual number of bytes sent as content, conforming servers ignore the whole request (usually returning a 400-499 range response code).
POST should have two newlines before the data, not after it.
"Accept-Charset: utf-8\r\n\r\n"
"dat=somedata\r\n",
精彩评论