📄 tcpsockettooldlg.cpp
字号:
// TcpSocketToolDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "TcpSocketTool.h"
#include "TcpSocketToolDlg.h"
#include ".\tcpsockettooldlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <sstream>
char e[3] = "@/";
/**************************************************************
功能:从 src 中找出前面的字母、数字等内含,即一个网页地址中主机名后面的部分
***************************************************************/
void GetAfterPosWithSlash(char * src, char ** d)
{
char * x;
if(src) x = src;
else {*d = 0; return ;}
while(x) {
if(*x >= 'a' && *x <= 'z') {x++; continue;}
else if(*x >= 'A' && *x <= 'Z') {x++; continue;}
else if(*x >= '0' && *x <= '9') {x++; continue;}
else if(*x == '.' || *x == '-' || *x == '_' || *x == '=') {x++; continue;}
else if(*x == ':' || *x == '/' || *x == '?' || *x == '&') {x++; continue;}
else {break;}
}
if(x) *d = x;
else *d = 0;
}
/**************************************************************
功能:为 myanchor 分配 len 大小的内存
***************************************************************/
void GetMemory(char ** myanchor, int len)
{
if(!(*myanchor)) (*myanchor) = (char *)malloc(len + 1);
else (*myanchor) = (char *)realloc((void *)(*myanchor), len + 1);
memset((*myanchor), 0, len + 1);
}
/**************************************************************
功能:在字符串 s 里搜索 x 字符,并设置指针 d 指向该位置
***************************************************************/
void Rstrchr(char * s, int x, char ** d)
{
int len = strlen(s) - 1;
while(len >= 0) {
if(x == s[len]) {(*d) = s + len; return;}
len--;
}
(*d) = 0;
}
/**************************************************************
功能:从字符串 src 中分析出网站地址和端口,并得到文件和目录
***************************************************************/
int GetHost( char * src, char ** web, char ** file, unsigned short * port, char ** dir) {
char * pA, * pB, * pC;
int len;
*port = 0;
if(!(*src)) return -1;
pA = src;
if(!strncmp(pA, "http://", strlen("http://"))) pA = src+strlen("http://");
/* else if(!strncmp(pA, "https://", strlen("https://"))) pA = src+strlen("https://"); */
else return 1;
pB = strchr(pA, '/');
if(pB) {
len = strlen(pA) - strlen(pB);
GetMemory(web, len);
memcpy((*web), pA, len);
if(*(pB+1)) {
Rstrchr(pB + 1, '/', &pC);
if(pC) len = strlen(pB + 1) - strlen(pC);
else len = 0;
if(len > 0) {
GetMemory(dir, len);
memcpy((*dir), pB + 1, len);
if(pC + 1) {
len = strlen(pC + 1);
GetMemory(file, len);
memcpy((*file), pC + 1, len);
}
else {
len = 1;
GetMemory(file, len);
memcpy((*file), e, len);
}
}
else {
len = 1;
GetMemory(dir, len);
memcpy((*dir), e + 1, len);
len = strlen(pB + 1);
GetMemory(file, len);
memcpy((*file), pB + 1, len);
}
}
else {
len = 1;
GetMemory(dir, len);
memcpy((*dir), e + 1, len);
len = 1;
GetMemory(file, len);
memcpy((*file), e, len);
}
}
else {
len = strlen(pA);
GetMemory(web, len);
memcpy((*web), pA, strlen(pA));
len = 1;
GetMemory(dir, len);
memcpy((*dir), e + 1, len);
len = 1;
GetMemory(file, len);
memcpy((*file), e, len);
}
pA = strchr((*web), ':');
if(pA)
{
*port = atoi(pA + 1);
*pA = 0;
}
else *port = 80;
return 0;
}
// CTcpSocketToolDlg 对话框
CTcpSocketToolDlg::CTcpSocketToolDlg(CWnd* pParent /*=NULL*/)
: CDialog(CTcpSocketToolDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pTcpSvrSocket = NULL;
m_pTcpCltSocket = NULL;
m_urlPath = "";
m_host = "";
m_port = 0;
m_firstRange = 0;
m_cookie = "";
m_referer = "";
m_userAgent = "";
m_user = "";
m_password = "";
m_extraHeader = "";
m_recvDataLen = 0;
}
void CTcpSocketToolDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST_MSG, m_msgList);
DDX_Control(pDX, IDC_EDIT_SOCKETID, m_socketId);
DDX_Control(pDX, IDC_EDIT_SENDMSG, m_sendMSG);
DDX_Control(pDX, IDC_EDIT_PORT, m_Port);
DDX_Control(pDX, IDC_EDIT_SERVERIP, m_serverIP);
DDX_Control(pDX, IDC_EDIT_SERVERPORT, m_serverPort);
}
BEGIN_MESSAGE_MAP(CTcpSocketToolDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON_CREATE, OnBnClickedButtonCreate)
ON_BN_CLICKED(IDC_BUTTON_SEND, OnBnClickedButtonSend)
ON_BN_CLICKED(IDC_BUTTON_CLIENTSOCKET, OnBnClickedButtonClientsocket)
ON_BN_CLICKED(IDC_BUTTON_CLTSEND, OnBnClickedButtonCltsend)
END_MESSAGE_MAP()
// CTcpSocketToolDlg 消息处理程序
BOOL CTcpSocketToolDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
m_Port.SetWindowText( "8888" );
this->m_serverIP.SetWindowText("10.3.1.174");
this->m_serverPort.SetWindowText( "8887");
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CTcpSocketToolDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CTcpSocketToolDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void WINAPI CTcpSocketToolDlg::OnRecvData(char *pData,int len,sockaddr_in destaddr,int socketId)
{
CString str;
//str.Format("<SocketID=%d>:MSG=%s",socketId,pData);
//m_msgList.AddString( str );
//str.Format("%d",socketId);
//m_socketId.SetWindowText( str );
m_recvDataLen += len;
}
void WINAPI CTcpSocketToolDlg::OnClose(int socketId,sockaddr_in destaddr)
{
CString str;
DWORD t = ::GetTickCount();
str.Format("<SocketID=%d>:Close()IP:%s PORT:%d Tick:%d 速度:%d 接收到数据大小:%d ",socketId, inet_ntoa( destaddr.sin_addr), destaddr.sin_port, t, (int)(this->m_recvDataLen)/((t - m_beginRecvTick)/1000), m_recvDataLen);
m_msgList.AddString( str );
}
void WINAPI CTcpSocketToolDlg::OnConnect(sockaddr_in destaddr,int socketId)
{
string s = sendRequest( this->m_urlPath.c_str(), m_host.c_str(), this->m_port, m_firstRange, m_cookie.c_str(), m_referer.c_str(), m_userAgent.c_str(), m_user.c_str(), m_password.c_str(), m_extraHeader.c_str() );
if( NULL != m_pTcpCltSocket )
{
m_pTcpCltSocket->SendData( (char *)s.c_str() , s.length() , socketId);
m_beginRecvTick = ::GetTickCount();
m_recvDataLen = 0;
}
CString str;
str.Format("<SocketID=%d>:Accept()IP:%s PORT:%d Tick:%d",socketId, inet_ntoa( destaddr.sin_addr), destaddr.sin_port, ::GetTickCount());
m_msgList.AddString( str );
}
void CTcpSocketToolDlg::OnBnClickedButtonCreate()
{
CString str;
m_Port.GetWindowText( str );
m_pTcpSvrSocket = new CTcpSvrSocket( (int)atoi( str ),this );
m_pTcpSvrSocket->Start();
}
BOOL CTcpSocketToolDlg::DestroyWindow()
{
// TODO: 在此添加专用代码和/或调用基类
if( NULL != m_pTcpSvrSocket )
{
m_pTcpSvrSocket->Stop();
delete m_pTcpSvrSocket;
m_pTcpSvrSocket = NULL;
}
if( NULL != m_pTcpCltSocket )
{
m_pTcpCltSocket->Stop();
delete m_pTcpCltSocket;
m_pTcpCltSocket = NULL;
}
return __super::DestroyWindow();
}
void CTcpSocketToolDlg::OnBnClickedButtonSend()
{
CString str,msg;
m_socketId.GetWindowText( str );
m_sendMSG.GetWindowText( msg );
if( NULL != m_pTcpSvrSocket )
{
m_pTcpSvrSocket->SendData( msg.GetBuffer(0),msg.GetLength(),(int)atoi( str ) );
}
}
void CTcpSocketToolDlg::OnBnClickedButtonClientsocket()
{
CString msg;
m_sendMSG.GetWindowText( msg );
if( !parseURL( msg.GetBuffer(0), m_urlPath, m_host, m_fileName, m_port ) )
return ;
if( m_urlPath.find("/") != 0 )
m_urlPath = "/" + m_urlPath;
CString str, ip, port;
m_Port.GetWindowText( str );
if( NULL != m_pTcpCltSocket )
{
m_pTcpCltSocket->Stop();
delete m_pTcpCltSocket;
m_pTcpCltSocket = NULL;
}
m_pTcpCltSocket = new CTcpCltSocket( (int)atoi( str.GetBuffer(0) ),this );
//this->m_serverIP.GetWindowText( ip );
//this->m_serverPort.GetWindowText( port );
sockaddr_in sa;
hostent* hp = gethostbyname ( m_host.c_str() );
if( hp )
{
memcpy (&sa.sin_addr, hp->h_addr, hp->h_length);
ip = inet_ntoa( sa.sin_addr );
}
m_pTcpCltSocket->Start( ip.GetBuffer(0), (unsigned short)m_port );
}
void CTcpSocketToolDlg::OnBnClickedButtonCltsend()
{
CString str,msg;
m_sendMSG.GetWindowText( msg );
if( NULL != m_pTcpCltSocket )
{
m_pTcpCltSocket->SendData( msg.GetBuffer(0),msg.GetLength(),(int)atoi( str ) );
}
}
string str_ultoa(unsigned long l)
{
ostringstream ss;
ss << l;
return ss.str();
}
string CTcpSocketToolDlg::sendRequest( string urlPath, string host, unsigned short port, __int64 firstRange, string cookie , \
string referer, string userAgent, string user, string password, \
string extraHeader)
{
string req;
req = "GET ";
req += urlPath;
req += " HTTP/1.0\r\n";
req += "Host: " + host;
if(port != 80) {
char tmpbuf[50];
wsprintf(tmpbuf, "%d", port);
req += ":";
req += tmpbuf;
}
req += "\r\n";
if(cookie.size() > 0)
req += "Cookie: " + cookie + "\r\n";
if(firstRange > 0) {
req += "Range: bytes=";
req += str_ultoa(firstRange) + "-";
req += "\r\n";
}
if(referer.size() > 0)
req += "Referer: " + referer + "\r\n";
if(userAgent.size() > 0)
req += "User-Agent: " + userAgent + "\r\n";
else
req += "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n";
/* if(user.size() > 0) {
req += "Authorization: ";
char* pass = basic_authentication_encode(user.c_str(), password.c_str());
req += pass;
free(pass);
req += "\r\n";
}
*/
if(extraHeader.size() > 0)
req += extraHeader;
req += "Accept: */*\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n"
"\r\n";
return req;
}
bool CTcpSocketToolDlg::parseURL( string _url, string &_urlPath, string &_host, string _fileName, unsigned short &_port )
{
char url[2048];
char *urlPath = new char[1024];
char *host = new char[1024];
char *fileName= new char[1024];
unsigned short port;
memset( url, 0, sizeof( url));
memcpy( url, _url.c_str(), _url.size() );
if( -1 == GetHost( (char *)url, (char **)&host, (char **)&fileName, &port, (char **)&urlPath ) )
{
delete []urlPath;
delete []host;
delete []fileName;
return false;
}
_urlPath = urlPath;
_urlPath += "/";
_urlPath += fileName;
_host = host;
_port = port;
_fileName = fileName;
delete []urlPath;
delete []host;
delete []fileName;
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -