根据客户需求,游戏过程当中,须要记录玩家的一些操做,造成录像功能.php
简要设计为: 玩家每次进行操做时,服务端提记录每一条通讯协议与数据,保存到文件中,当玩家须要查看录像时,客户端下载通讯协议信息,模拟玩家的操做过程.为方便写入大量数据文件信息,不对服务器机器形成影响(容量太大,硬盘不够),这里采用c++中发送http请求到web服务器,直接调用php的文件操做方法,实现文件记录功能.html
1.c++中的信息发送到web服务器,这里是c++直接拼数据信息nginx
简要代码实现:c++
套接字:web
http_socet = socket(AF_INET,SOCK_STREAM,0);
服务器
sockaddr_in s_add;
memset(&s_add, sizeof(s_add), 0);
s_add.sin_family = AF_INET;
s_add.sin_addr.s_addr = inet_addr(ip);
s_add.sin_port = htons(port);
if (0 != connect(http_socket, (sockaddr*)&s_add, sizeof(sockaddr)))
{
LOG_WARN("%s", "connect to http server failed!");
break;
app
}socket
拼接数据信息:spa
// boundary
std::string boundary = "----------------------------7e6e3ed55865";
// body
ostringstream http_body;
http_body << "--" << boundary << "\r\n";
http_body << "Content-Disposition: form-data; name=\"file\"; filename=\"" << file_name << "\"\r\n";
http_body << "Content-Type: application/octet-stream\r\n";
http_body << "\r\n";
record_info.SerializeToOstream(&http_body); //这是是记录的操做信息进行序列化
http_body << "\r\n";
http_body << "--" << boundary << "--\r\n";
设计
// http header
ostringstream http_header;
http_header << "POST /upload HTTP/1.1\r\n";
http_header << "Host: " << ip << ":" << port << "\r\n";
http_header << "Content-Length: " << http_body.str().size() << "\r\n";
http_header << "Content-Type: multipart/form-data; boundary=" << boundary << "\r\n";
http_header << "\r\n";
string http_data = http_header.str() + http_body.str();
LOG_DEBUG("%s", http_data.c_str());
if (SOCKET_ERROR == send(http_socket, http_data.c_str(), (int)http_data.size(), 0))
{
LOG_WARN("%s", "send to http server failed!");
break;
}
char response[1024] = { 0 };
if (recv(http_socket, response, sizeof(response), 0) > 0)
{
LOG_DEBUG("http server response : %s", response);
}
else
{
LOG_WARN("%s", "recv http server response failed!");
}
if (http_socket != INVALID_SOCKET)
{
#ifdef WIN32
closesocket(http_socket);
#else
close(http_socket);
#endif
}
到这里,c++服务器成功将信息发送出去.
nginx 配置信息
下载模块
server {
listen 8001;
location / {
root /data/app/nginx/htdocs/webdir/record_1002;
}
}
上传模块
server {
listen 9001;
server_name upload;
rewrite "^/(.*)$" /$1.php break;
location / {
root html;
index index.html index.htm;
}
location ~ \.php$ {
root /data/app/nginx/htdocs/webdir/record_1002;
fastcgi_pass 127.0.0.1:9999;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
服务端php代码直接照搬php教程里面的文件操做模块
<?php
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
$stored_path = "./" . basename($_FILES['file']['name']);
move_uploaded_file($_FILES["file"]["tmp_name"], $stored_path);
echo "stored in " . $stored_path;
}
?>
web端是完整上传文件代码
c++端是主要的发送数据代码,其余代码简略.