2019-07-28 10:31:56 +08:00
|
|
|
|
#include "stdafx.h"
|
2016-10-21 15:02:50 +08:00
|
|
|
|
|
|
|
|
|
static bool handshake(acl::socket_stream& conn)
|
|
|
|
|
{
|
|
|
|
|
acl::http_request req(&conn);
|
|
|
|
|
acl::http_header& hdr = req.request_header();
|
|
|
|
|
hdr.set_ws_key("123456789")
|
|
|
|
|
.set_ws_version(13)
|
|
|
|
|
.set_upgrade("websocket")
|
|
|
|
|
.set_keep_alive(true);
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!req.request(NULL, 0)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("request error\r\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int status = req.http_status();
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (status != 101) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("invalid http status: %d\r\n", status);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool send_file(acl::websocket& ws, const char* filepath)
|
|
|
|
|
{
|
|
|
|
|
acl::ifstream in;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!in.open_read(filepath)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("open %s error %s\r\n", filepath, acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long long size = in.fsize();
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (size <= 0) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("filename: %s, invalid size: %lld\r\n", filepath, size);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
acl::string buf;
|
|
|
|
|
buf.basename(filepath);
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
unsigned mask = ~0;
|
2016-10-21 15:02:50 +08:00
|
|
|
|
ws.set_frame_fin(true)
|
|
|
|
|
.set_frame_opcode(acl::FRAME_TEXT)
|
2019-09-17 16:51:43 +08:00
|
|
|
|
.set_frame_payload_len(buf.size())
|
|
|
|
|
.set_frame_masking_key(mask);
|
2016-10-21 15:02:50 +08:00
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!ws.send_frame_data(buf, buf.size())) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("send filenam error %s\r\n", acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf.format("%lld", size);
|
|
|
|
|
ws.reset().set_frame_fin(true)
|
|
|
|
|
.set_frame_opcode(acl::FRAME_TEXT)
|
|
|
|
|
.set_frame_payload_len(buf.size());
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!ws.send_frame_data(buf, buf.size())) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("send file size error %s\r\n", acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long long total = 0;
|
|
|
|
|
char cbuf[128000];
|
2019-09-17 16:51:43 +08:00
|
|
|
|
while (!in.eof()) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
int ret = in.read(cbuf, sizeof(cbuf), false);
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (ret == -1) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
break;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
}
|
2016-10-21 15:02:50 +08:00
|
|
|
|
|
|
|
|
|
printf(">>send %d\r\n", ret);
|
|
|
|
|
ws.reset().set_frame_fin(true)
|
|
|
|
|
.set_frame_opcode(acl::FRAME_BINARY)
|
|
|
|
|
.set_frame_payload_len(ret);
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!ws.send_frame_data(cbuf, ret)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("send data error %s\r\n", acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
total += ret;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (total % 10240000 == 0) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
sleep(1);
|
2019-09-17 16:51:43 +08:00
|
|
|
|
}
|
2016-10-21 15:02:50 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf(">>total send: %lld\r\n", total);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool read_reply(acl::websocket& ws)
|
|
|
|
|
{
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!ws.read_frame_head()) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("read_frame_head error %s\r\n", acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char cbuf[1024];
|
|
|
|
|
unsigned char opcode = ws.get_frame_opcode();
|
2019-09-17 16:51:43 +08:00
|
|
|
|
switch (opcode) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
case acl::FRAME_TEXT:
|
|
|
|
|
case acl::FRAME_BINARY:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("invalid opcode: 0x%x\r\n", opcode);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ret = ws.read_frame_data(cbuf, sizeof(cbuf) - 1);
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (ret <= 0) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("read_frame_data error\r\n");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
cbuf[ret] = 0;
|
|
|
|
|
printf("reply from server: %s, len: %d\r\n", cbuf, ret);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool upload(const char* addr, const char* filepath)
|
|
|
|
|
{
|
|
|
|
|
acl::socket_stream conn;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!conn.open(addr, 30, 30)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
printf("connect %s error %s\r\n", addr, acl::last_serror());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!handshake(conn)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
return false;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
}
|
2016-10-21 15:02:50 +08:00
|
|
|
|
|
|
|
|
|
acl::websocket ws(conn);
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!send_file(ws, filepath)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
return false;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
}
|
2016-10-21 15:02:50 +08:00
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (!read_reply(ws)) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
return false;
|
2019-09-17 16:51:43 +08:00
|
|
|
|
}
|
2016-10-21 15:02:50 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void usage(const char* proc)
|
|
|
|
|
{
|
|
|
|
|
printf("usage: %s -h [help] -s server_addr -f filename\r\n", proc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
|
{
|
2019-07-28 10:31:56 +08:00
|
|
|
|
// <20><>ʼ<EFBFBD><CABC> acl <20><>
|
2016-10-21 15:02:50 +08:00
|
|
|
|
acl::acl_cpp_init();
|
2019-07-28 10:31:56 +08:00
|
|
|
|
acl::log::stdout_open(true); // <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD>
|
2016-10-21 15:02:50 +08:00
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
|
|
acl::string addr, filename;
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
while ((ch = getopt(argc, argv, "hf:s:")) > 0) {
|
|
|
|
|
switch (ch) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
case 'h':
|
|
|
|
|
usage(argv[0]);
|
|
|
|
|
return 0;
|
|
|
|
|
case 'f':
|
|
|
|
|
filename = optarg;
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
|
|
|
|
addr = optarg;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-17 16:51:43 +08:00
|
|
|
|
if (addr.empty() || filename.empty()) {
|
2016-10-21 15:02:50 +08:00
|
|
|
|
usage(argv[0]);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
upload(addr, filename);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|