我已经购买了VPS作为远程服务器,并在该远程服务器上部署了shadowsocks作为代理。
案例1:
当我使用uTorrent通过Shadowsocks下载文件时,速度可能达到10 MB /秒(80 Mbits /秒)。该图是:
--------------------------- -------------------------- ---------
| Local computer | | Remote server | | |
| ------------ | 80 Mbits/sec | ----------- | | |
| uTorrent<-->| shadowsocks||<---------------->| |shadowsocks|<--------------->|Internet |
| | client || | | server | | | |
| ------------ | | ----------- | | |
--------------------------- -------------------------- ---------
案例2:
现在,我用C ++编写了一个客户机/服务器程序。但是网络速度极低,这是我的测试结果:
客户端:下载速度
t_lRecvTotalBytes = 1024000字节
t_lRecvTotalTime = 2942410微秒。
网络速度:2.7 MBit / s
服务器:上传速度
t_lRecvTotalBytes = 1024000字节
t_lRecvTotalTime = 1741625微秒。
网络速度:4.5 MBit / s
该图是:
--------------------------- --------------------------
| Local computer | | Remote server |
| --------------- |2.7~4.5 Mbits/sec | -------------- |
| | My C++ client |<------------------------->| My C++ server| |
| --------------- | | -------------- |
| | | |
--------------------------- --------------------------
案例3:
iperf3
用于测试local computer
和Remote server
之间的带宽。结果是:
[ID]间隔传输比特率
[5] 0.00-10.00秒7.25 MBytes 6.08 Mbits / sec
[5] 10.00-20.00秒11.6 MBytes 9.73 Mbits / sec
[5] 20.00-30.00秒12.2 MBytes 10.3 Mbits / sec
[5] 30.00-40.00秒11.4 MBytes 9.53 Mbits / sec
[5] 40.00-50.00秒12.0 MBytes 10.0 Mbits / sec
[5] 50.00-60.00秒8.28 MBytes 6.94 Mbits / sec
[ID]间隔传输比特率记录
[5] 0.00-60.00秒62.9 MBytes 8.79 Mbits / sec 222个发送者
[5] 0.00-60.00秒62.7 MBytes 8.77 Mbits / sec接收器
该图是:
--------------------------- --------------------------
| Local computer | | Remote server |
| --------------- | 8.8 Mbits/sec | -------------- |
| | iperf3 client |<------------------------->| iperf3 server| |
| --------------- | | -------------- |
| | | |
--------------------------- --------------------------
我的客户端/服务器代码
server.cpp
#include <iostream>
#include <arpa/inet.h>
#include <string>
#include <chrono>
#include <unistd.h>
#include <stdlib.h>
#include <iomanip>
#include <signal.h>
#include <fcntl.h>
#define PORT (7549)
#define CYCLE_TIME (100)
int g_iSockFd;
void sigQuitHandler(int signal) {
std::cout << "received SIGQUIT, doing graceful shutting down ..."
<< std::endl;
close(g_iSockFd);
exit(1);
}
void sigIntrHandler(int signal) {
std::cout << "received SIGINT, doing graceful shutting down ..."
<< std::endl;
close(g_iSockFd);
exit(1);
}
/*
* FUNCTION : enable or disable blocking of a file descriptor (socket)
* @PARAM : fd file descriptor to be processed
* @PARAM : blocking a bool flag to indicate blocking or non-blocking
* true ----> blocking
* false ----> non-blocking
* @RETURN : true on success
* false if there was an error
*/
bool SetSocketBlockingEnabled(int fd, bool blocking) {
if (fd < 0) {
return false;
}
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
return false;
}
flags = blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK);
return (fcntl(fd, F_SETFL, flags) == 0) ? true : false;
}
int main(int argc, char** argv) {
// register signal handler function
struct sigaction t_struQuitSigAction;
struct sigaction t_struIntrSigAction;
t_struQuitSigAction.sa_handler = sigQuitHandler;
t_struQuitSigAction.sa_flags = 0;
sigemptyset(&t_struQuitSigAction.sa_mask);
sigaction(SIGQUIT, &t_struQuitSigAction, 0);
t_struIntrSigAction.sa_handler = sigIntrHandler;
t_struIntrSigAction.sa_flags = 0;
sigemptyset(&t_struIntrSigAction.sa_mask);
sigaction(SIGINT, &t_struIntrSigAction, 0);
// init socket parameter
char t_cRecvBuffer[102400];
struct sockaddr_in t_struSockAddr;
memset(&t_struSockAddr, 0, sizeof(t_struSockAddr));
int t_iOpt = 1;
// IPv4
t_struSockAddr.sin_family = AF_INET;
t_struSockAddr.sin_addr.s_addr = INADDR_ANY; // inet_addr("127.0.0.1");
t_struSockAddr.sin_port = htons(PORT);
// create socket
int g_iSockFd = socket(AF_INET, SOCK_STREAM, 0);
if (g_iSockFd == -1) {
std::cout << "Error accurs when creating socket."
<< std::endl << "System exits abnormally." << std::endl;
return -1;
}
int t_iError;
if ((t_iError = setsockopt(g_iSockFd, SOL_SOCKET, SO_REUSEADDR,
&t_iOpt, sizeof(t_iOpt))) < 0) {
std::cout << "reuseaddr setsockopt fail. error = "
<< t_iError << std::endl;
return -1;
}
if ((t_iError = setsockopt(g_iSockFd, SOL_SOCKET, SO_REUSEPORT,
&t_iOpt, sizeof(t_iOpt))) < 0) {
std::cout << "reuseport setsockopt fail. error = "
<< t_iError << std::endl;
return -1;
}
SetSocketBlockingEnabled(g_iSockFd, true);
if (bind(g_iSockFd, (struct sockaddr *)&t_struSockAddr,
sizeof(t_struSockAddr)) < 0) {
std::cout << "bind fail." << std::endl;
return -1;
}
if (listen(g_iSockFd, 10) < 0) {
std::cout << "listen fail." << std::endl;
return -1;
}
int t_iNewSocket;
while (1) {
std::string t_strResponse(10240, 0);
struct sockaddr_in t_struClientAddr;
socklen_t t_ClientAddrLen = 0;
memset(&t_struClientAddr, 0, sizeof(t_struClientAddr));
if ((t_iNewSocket = accept(g_iSockFd,
(struct sockaddr*)&t_struClientAddr,
&t_ClientAddrLen)) < 0) {
continue;
}
else {
std::cout << "accept successfully." << std::endl;
}
// recv
long t_lRecvTotalBytes = 0;
long t_lRecvTotalTime = 0;
double t_dSpeed = 0.0;
std::chrono::high_resolution_clock::time_point t_StartTime;
std::chrono::high_resolution_clock::time_point t_EndTime;
bool t_bHasBegin = false;
while (1) {
int t_iRecvBytes = recv(t_iNewSocket, t_cRecvBuffer,
sizeof(t_cRecvBuffer), 0);
if (t_iRecvBytes <= 0) {
std::cout << "Error accurs when receiving. " << std::endl;
break;
}
else {
if (t_bHasBegin == false) {
t_bHasBegin = true;
t_StartTime = std::chrono::high_resolution_clock::now();
}
t_lRecvTotalBytes += t_iRecvBytes;
std::string t_strRecv(t_cRecvBuffer, t_iRecvBytes);
std::cout << "Receiving " << t_iRecvBytes << "/"
<< t_lRecvTotalBytes
<< " bytes. " << std::endl
<< "Msg ends with: "
<< int(t_strRecv[t_iRecvBytes - 1])
<< std::endl;
if (t_cRecvBuffer[t_iRecvBytes - 1] == 1) {
std::cout << "recv finished." << std::endl;
break;
}
}
}
t_EndTime = std::chrono::high_resolution_clock::now();
t_lRecvTotalTime =
std::chrono::duration_cast<std::chrono::microseconds>(
t_EndTime - t_StartTime
).count();
t_dSpeed = double(t_lRecvTotalBytes) / t_lRecvTotalTime
* 1000000 * 8 / 1024 / 1024;
std::cout << "t_lRecvTotalBytes = "
<< t_lRecvTotalBytes << " Bytes" << std::endl;
std::cout << "t_lRecvTotalTime = "
<< t_lRecvTotalTime << " microseconds." << std::endl;
std::cout << "network speed: "
<< std::setprecision(2)
<< t_dSpeed << " MBit/s" << std::endl;
// response
for (int i = 0; i < CYCLE_TIME; ++i) {
if (i == CYCLE_TIME - 1) {
t_strResponse[t_strResponse.size() - 1] = 1;
}
int t_iSendBytes = send(t_iNewSocket, t_strResponse.c_str(), \
t_strResponse.size(), 0);
if (t_iSendBytes != t_strResponse.size()) {
std::cout << "send error" << std::endl;
return -1;
}
else {
std::cout << "Send message successfully. "
<< std::endl << "CNT = " << i << std::endl
<< "size: " << t_iSendBytes << " Bytes." << std::endl;
}
}
// close
close(t_iNewSocket);
std::cout << "t_lRecvTotalBytes = "
<< t_lRecvTotalBytes << " Bytes" << std::endl;
std::cout << "t_lRecvTotalTime = "
<< t_lRecvTotalTime << " microseconds." << std::endl;
std::cout << "network speed: "
<< std::setprecision(2)
<< t_dSpeed << " MBit/s" << std::endl;
}
return 0;
}
client.cpp
#include <iostream>
#include <arpa/inet.h>
#include <string>
#include <chrono>
#include <unistd.h>
#include <stdlib.h>
#include <iomanip>
#include <signal.h>
#define CYCLE_TIME (100)
#define PORT (7549)
#define LOCAL_MODE (0)
#define REMOTE_MODE (1)
int g_iSockFd;
void sigQuitHandler(int signal) {
std::cout << "received SIGQUIT, doing graceful shutting down ..."
<< std::endl;
close(g_iSockFd);
exit(1);
}
void sigIntrHandler(int signal) {
std::cout << "received SIGINT, doing graceful shutting down ..."
<< std::endl;
close(g_iSockFd);
exit(1);
}
int main(int argc, char** argv) {
int t_iWorkMode = LOCAL_MODE;
if (argc == 2) {
int t_iTempWorkMode = atoi(argv[1]);
switch (t_iTempWorkMode) {
case LOCAL_MODE:
t_iWorkMode = LOCAL_MODE;
break;
case REMOTE_MODE:
t_iWorkMode = REMOTE_MODE;
break;
default:
std::cout << "mode should be 1 or 2. LOCAL_MODE is used."
<< std::endl;
t_iWorkMode = LOCAL_MODE;
}
}
// register signal handler function
struct sigaction t_struQuitSigAction;
struct sigaction t_struIntrSigAction;
t_struQuitSigAction.sa_handler = sigQuitHandler;
t_struQuitSigAction.sa_flags = 0;
sigemptyset(&t_struQuitSigAction.sa_mask);
sigaction(SIGQUIT, &t_struQuitSigAction, 0);
t_struIntrSigAction.sa_handler = sigIntrHandler;
t_struIntrSigAction.sa_flags = 0;
sigemptyset(&t_struIntrSigAction.sa_mask);
sigaction(SIGINT, &t_struIntrSigAction, 0);
struct in_addr t_in_addr;
memset(&t_in_addr, 0, sizeof(t_in_addr));
if (inet_aton("127.0.0.1", &t_in_addr) == 0) {
std::cout << "inet_aton fail." << std::endl;
return -1;
}
std::string t_strMsg;
char t_cRecvBuffer[102400];
// init socket parameter
struct sockaddr_in t_struSockAddr;
memset(&t_struSockAddr, 0, sizeof(t_struSockAddr));
// IPv4
t_struSockAddr.sin_family = AF_INET;
// remote IP address
if (t_iWorkMode == REMOTE_MODE) {
t_struSockAddr.sin_addr.s_addr = inet_addr("remote server IP address");
}
else {
t_struSockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
}
// remote port
t_struSockAddr.sin_port = htons(PORT);
// create socket
int g_iSockFd = socket(AF_INET, SOCK_STREAM, 0);
if (g_iSockFd == -1) {
std::cout << "Error accurs when creating socket."
<< std::endl << "System exits abnormally." << std::endl;
return -1;
}
if (connect(g_iSockFd, (struct sockaddr *)&t_struSockAddr, \
sizeof(struct sockaddr)) < 0) {
std::cout << std::endl
<< "Error accurs when connecting to server."
<< std::endl << "System exits abnormally." << std::endl;
return -1;
}
std::cout << "Connected to remote server." << std::endl;
int t_iSendBytes = 0;
// send request
t_strMsg = std::string(10240, 0);
for (int i = 0; i < CYCLE_TIME; ++i) {
// 1 means the end of message
if (i == CYCLE_TIME - 1) {
t_strMsg[t_strMsg.size() - 1] = 1;
}
t_iSendBytes = send(g_iSockFd, t_strMsg.c_str(), \
t_strMsg.size(), 0);
if (t_iSendBytes != t_strMsg.size()) {
std::cout << "Request message is not "
<< "sent completely. System exits abnormally. "
<< "t_iSendBytes = " << t_iSendBytes << " Bytes. " << std::endl;
return -1;
}
else {
std::cout << "CNT = " << i << std::endl
<< "Msg ends with "
<< int(t_strMsg[t_strMsg.size() - 1]) << std::endl
<< "Send request message. Bytes: " << t_iSendBytes
<< std::endl;
}
}
std::cout << "Send finished." << std::endl;
std::cout << "Begin to receive ..." << std::endl;
long t_lRecvTotalBytes = 0;
long t_lRecvTotalTime = 0;
double t_dSpeed = 0.0;
std::chrono::high_resolution_clock::time_point t_StartTime;
std::chrono::high_resolution_clock::time_point t_EndTime;
t_StartTime = std::chrono::high_resolution_clock::now();
memset(t_cRecvBuffer, 0, sizeof(t_cRecvBuffer));
while (1) {
int t_iRecvBytes = recv(g_iSockFd, t_cRecvBuffer, sizeof(t_cRecvBuffer), 0);
if (t_iRecvBytes == -1) {
std::cout << "Error accurs when receiving. "
<< std::endl << "System exits abnormally.";
return -1;
}
else if (t_iRecvBytes > 0) {
t_lRecvTotalBytes += t_iRecvBytes;
std::string t_strRecv(t_cRecvBuffer, t_iRecvBytes);
// std::cout << t_strRecv;
std::cout << "Receiving " << t_iRecvBytes << "/"
<< t_lRecvTotalBytes << " bytes." << std::endl;
// 1 means the end of message.
if (t_cRecvBuffer[t_iRecvBytes - 1] == 1) {
std::cout << "recv finished." << std::endl;
break;
}
}
}
t_EndTime = std::chrono::high_resolution_clock::now();
t_lRecvTotalTime =
std::chrono::duration_cast<std::chrono::microseconds>(
t_EndTime - t_StartTime
).count();
t_dSpeed = double(t_lRecvTotalBytes) / t_lRecvTotalTime
* 1000000 * 8 / 1024 / 1024;
std::cout << "t_lRecvTotalBytes = "
<< t_lRecvTotalBytes << " Bytes" << std::endl;
std::cout << "t_lRecvTotalTime = "
<< t_lRecvTotalTime << " microseconds." << std::endl;
std::cout << "network speed: "
<< std::setprecision(2)
<< t_dSpeed << " MBit/s" << std::endl;
// close
close(g_iSockFd);
return 0;
}
目标
目标是我的客户端和服务器程序之间的网络速度可以达到约80 Mbits / sec。但是我找不到解决问题的方法。 utorrent和iperf测试的网络速度让我感到困惑。
如果有人可以帮助我,我将不胜感激。谢谢!