7,540
社区成员
发帖
与我相关
我的任务
分享
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define WINSOCK_VERSION MAKEWORD(2,2) // winsock版本
//-----------------------------------------------------------------------------
// Name: TCP_Req()
// Desc: 向指定端口的指定地址发送TCP数据包
// 返回时,输入数据的缓冲区存放接收的数据,输入数据的长度的变量存放接收的数据的长度
// 因为传输的不一定是文本,所以数据结尾没有空字符
//-----------------------------------------------------------------------------
int TCP_Req(char const * const host_name, WORD const host_port,
char * const buffer, int const buffer_size, int &data_len)
{
assert(host_name && *host_name);
assert(buffer && *buffer);
// 缓冲区大小不小于其中的数据长度
assert(buffer_size > 0 && data_len > 0 && buffer_size >= data_len);
// 初始化Winsock
WSADATA wsadata;
if(WSAStartup(WINSOCK_VERSION, &wsadata))
return -1; // 初始化Winsock出错
// 得到主机信息
LPHOSTENT lphostent = gethostbyname(host_name);
if(lphostent == NULL)
{
WSACleanup();
return -2; // 无法得到主机信息
}
// 填写连接地址信息
SOCKADDR_IN saServer;
saServer.sin_family = AF_INET;
saServer.sin_port = htons(host_port);
saServer.sin_addr = *((LPIN_ADDR)*lphostent->h_addr_list);
// 创建Socket,向主机发出连接请求
SOCKET hsocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
int nRet = connect(hsocket, (LPSOCKADDR)&saServer, sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR)
{
closesocket(hsocket);
WSACleanup();
return -3; // 无法连接到主机
}
// 发送数据包
nRet = send(hsocket, buffer, data_len, 0);
if (nRet == SOCKET_ERROR)
{
closesocket(hsocket);
WSACleanup();
return -4; // 发送数据包出错
}
// 接收数据,直到无数据传入
char *p_buffer = buffer;
int len = buffer_size;
data_len = 0;
nRet = 1;
while(nRet > 0)
{
nRet = recv(hsocket, p_buffer, len, 0);
// 收到数据后,把缓冲空间指针移到收到的数据后,并减少剩余空间大小,为下一次接收做准备
if (nRet > 0)
{
p_buffer += nRet;
len -= nRet;
// 如果某次接收后缓冲空间刚好用光(不会出现空间不够还正常返回的情况(len<0)),则跳出
// 如果这里不处理,recv()收到为0的长度后可能会返回错误(for byte stream sockets only)
if (len == 0)
{
data_len = buffer_size;
break;
}
}
// 数据接收完毕
else if (nRet == 0)
{
data_len = (int)(p_buffer - buffer);
break;
}
// 接收数据时发生错误
else
{
nRet = WSAGetLastError();
// 如果数据过长,缓冲空间放不下,则能放多少就放多少,不返回错误
if (nRet == WSAEMSGSIZE)
{
data_len = buffer_size;
break;
}
// 如果是其他错误,则返回出错
else
{
closesocket(hsocket);
WSACleanup();
return -5; // recv()其他错误
}
}
} // end while
closesocket(hsocket);
WSACleanup();
return 0;
} // end TCP_Req
TCP_Req("192.168.1.1", 80, req, sizeof(req), data_len);
// 发送重启路由器请求时的HTTP数据的开始部分
const char req_begin_reboot[] =
"GET /userRpm/SysRebootRpm.htm?Reboot=%D6%D8%C6%F4%C2%B7%D3%C9%C6%F7 HTTP/1.1\r\n"
"Host: 192.168.1.1\r\n"
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11\r\n"
"Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
"Accept-Language: zh-cn,zh;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 300\r\n"
"Connection: keep-alive\r\n"
"Referer: http://192.168.1.1/userRpm/SysRebootRpm.htm\r\n"
"Authorization: Basic ";