Skip to content

Instantly share code, notes, and snippets.

@KeithLin724
Last active December 28, 2022 08:35
Show Gist options
  • Save KeithLin724/06d260ec65a39fa2668adeb5bb876e6c to your computer and use it in GitHub Desktop.
Save KeithLin724/06d260ec65a39fa2668adeb5bb876e6c to your computer and use it in GitHub Desktop.
TCPIP_Tools

TCP-IP tools

written by KYLiN


here is put some tools using for tcp-tp develop

#pragma once
#ifndef __KYFUNCLITE_H__
#define __KYFUNCLITE_H__
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
// https://www.twblogs.net/a/5c3ed65fbd9eee35b21e0b01
#include <sstream>
#include <vector>
#include <utility>
#include <exception>
// https://stackoverflow.com/questions/16854308/do-i-need-a-return-after-throwing-exception-c-and-c
using std::pair;
using std::vector;
using std::stringstream;
using std::string;
using std::wstring;
using std::exception;
// define
#define __KYFUNC_BUFFER 5000
namespace KYFuncLite {
class Socket {
public:
static constexpr auto Af_Inet = AF_INET;
static constexpr auto Stream = SOCK_STREAM;
static constexpr auto Dgram = SOCK_DGRAM;
static constexpr auto Normal = 0;
static constexpr auto NoMoreRecv = 0;
static constexpr auto NoMoreSend = 1;
static constexpr auto NoRecvSend = 2;
public:
inline Socket() {
try {
this->__openWinSocket();
}
catch (const std::exception& e) {
throw e;
}
}
inline Socket(const SOCKET& socketIn) {
this->_socket = socketIn;
}
inline Socket(const int32_t& af, const int32_t& type, const int32_t& protocol) {
try {
this->__openWinSocket();
this->setSocket(af, type, protocol);
}
catch (const std::exception& e) {
throw e;
}
}
inline ~Socket() {
this->closeSocket();
this->WSACleanUp();
}
inline Socket& setSocket(const SOCKET& socketIn) {
this->_socket = socketIn;
return *this;
}
inline Socket& setSocket(const int32_t& af, const int32_t& type, const int32_t& protocol) {
this->_socket = socket(af, type, protocol);
if (this->_socket == INVALID_SOCKET) {
throw exception("Socket is INVALID_SOCKET");
}
return *this;
}
inline const SOCKET& getSocket() const {
return this->_socket;
}
inline void BindBuilder(const sockaddr& addr) const {
int32_t _res = bind(this->_socket, &addr, sizeof(sockaddr));
if (_res < 0) {
throw exception("Socket Error: bind error");
}
}
inline void ConnectorBuilder(const sockaddr& name) const {
int32_t _res = connect(this->_socket, &name, sizeof(sockaddr));
if (_res < 0) {
throw exception("Socket error (about connect)");
}
}
inline void ListenerBuilder(const int32_t& backlog) const {
int32_t _res = listen(this->_socket, backlog);
if (_res < 0) {
throw exception("Socket Error : listener error");
}
}
inline pair<SOCKET, sockaddr> AcceptBuilder() const {
sockaddr _sockaddrRes;
int32_t _len = sizeof(sockaddr);
SOCKET _res = accept(this->_socket, &_sockaddrRes, &_len);
if (_res == INVALID_SOCKET) {
throw exception("INVALID Socket : accept builder error");
}
return pair<SOCKET, sockaddr>(_res, _sockaddrRes);
}
// for tcp recv
inline string doRecv(const int32_t& flags = 0) const {
vector<char> buf(__KYFUNC_BUFFER);
int32_t nBytes = recv(this->_socket, buf.data(), buf.size(), flags);
if (nBytes < 0) {
throw exception("doRecv: data length less than 0");
}
buf.resize(nBytes);
return string(buf.begin(), buf.end());
}
// for udp recv
inline string doRecvFrom(sockaddr& fromAddr, const int32_t& flags = 0) const {
vector<char> buf(__KYFUNC_BUFFER);
int32_t fromLen = sizeof(sockaddr);
int32_t nBytes = recvfrom(this->_socket, buf.data(), buf.size(), flags, &fromAddr, &fromLen);
if (nBytes < 0) {
throw exception("doRecvFrom: data length less than 0");
}
buf.resize(nBytes);
return string(buf.begin(), buf.end());
}
// for tcp send
inline void doSend(const string& msg, const int32_t& flags = 0) const {
int32_t _res = send(this->_socket, msg.c_str(), msg.length(), flags);
if (_res == SOCKET_ERROR) {
throw exception("send : socket error");
}
}
// for udp sendto
inline void doSendTo(const string& msg, const sockaddr& fromAddr, const int32_t& flags = 0) const {
int32_t _res = sendto(this->_socket, msg.c_str(), msg.length(), flags, &fromAddr, sizeof(sockaddr));
if (_res == SOCKET_ERROR) {
throw exception("sendto : socket error");
}
}
inline void shutDown(const int32_t& how) const {
int32_t _res = shutdown(this->_socket, how);
if (_res < 0) {
throw exception("Socket Error: shut down");
}
}
inline void closeSocket() const {
int32_t _res = closesocket(this->_socket);
if (_res < 0) {
throw exception("Socket Error : close socket error");
}
}
inline void WSACleanUp() const {
int32_t _res = WSACleanup();
if (_res < 0) {
throw exception("WSA clean up error");
}
}
//operator
inline Socket& operator= (const SOCKET& sockObj) {
this->_socket == sockObj;
return *this;
}
inline bool operator== (const Socket& socketObj) const {
return this->_socket == socketObj._socket;
}
inline bool operator!= (const Socket& socketObj) const {
return this->_socket != socketObj._socket;
}
private:
inline const void __openWinSocket() {
int32_t _res = WSAStartup(0x202, &this->_wsdata);
if (_res < 0) {
throw exception("cant open the winSocket");
}
}
private:
SOCKET _socket;
WSADATA _wsdata;
};
class SocketMonitor {
public:
inline SocketMonitor(const Socket& sock) {
FD_ZERO(&this->_fdSock);
FD_SET(sock.getSocket(), &this->_fdSock);
this->_fdRead = this->_fdSock;
}
~SocketMonitor() {
}
inline void addPoll(const Socket& sock) {
FD_SET(sock.getSocket(), &this->_fdSock);
}
inline void popPoll(const Socket& sock) {
FD_CLR(sock.getSocket(), &this->_fdSock);
}
inline void listen() {
this->_fdRead = this->_fdSock;
int32_t res = select(0, &this->_fdRead, 0, 0, 0); // only read
if (res == -1) {
throw std::invalid_argument("select error");
}
}
inline fd_set get_fd_data() const {
return this->_fdRead;
}
private:
fd_set _fdSock, _fdRead;
};
// func
inline sockaddr& make_sockaddr(const ADDRESS_FAMILY& family, const uint16_t& port, const uint64_t& addr) {
sockaddr _res = {};
sockaddr_in* ptr = (sockaddr_in*)&_res;
ptr->sin_family = family;
ptr->sin_port = port;
ptr->sin_addr.s_addr = addr;
return _res;
}
inline const wstring& Big5ToUniCode(char* big5, const uint32_t& len) {
wchar_t* uniCode = new wchar_t[len] {0};
MultiByteToWideChar(950, 0, big5, -1, uniCode, len);
return wstring(uniCode, len);
}
inline const string& UniCodeToBig5(wchar_t* uniCode, const uint32_t& len) {
char* big5 = new char[len] {0};
WideCharToMultiByte(950, 0, uniCode, -1, big5, len, NULL, NULL);
big5[len] = 0;
return string(big5, len);
}
inline const vector<string>& split_string(const string& inputStr, const char& chr) {
stringstream ss;
string tmpStr;
vector<string> res;
ss << inputStr;
while (getline(ss, tmpStr, chr)) {
res.push_back(tmpStr);
}
return res;
}
}
#endif // !__KYFUNCLITE_H__
MIT License
Copyright (c) 2022 Keith Lin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#ifndef __SUPER_TINY_TCPIP_TOOLS__
#define __SUPER_TINY_TCPIP_TOOLS__
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <vector>
#include <sstream>
#include <stdexcept>
namespace KYTinyTools {
static constexpr auto BUFF = 2000;
// TeleRecv
inline std::vector<char> TeleRecv(const SOCKET& socket, const std::int32_t& flags = 0) {
std::vector<char> buf(BUFF);
int32_t nBytes = recv(socket, buf.data(), buf.size(), flags);
if (nBytes < 0) {
throw std::invalid_argument("TeleRecv: data length less than 0");
}
buf.resize(nBytes);
return buf;
}
// TeleRecvFrom
inline std::vector<char> TeleRecvFrom(const SOCKET& socket, sockaddr& fromAddr, const int32_t& flags = 0) {
std::vector<char> buf(BUFF);
int32_t fromLen = sizeof(sockaddr);
int32_t nBytes = recvfrom(socket, buf.data(), buf.size(), flags, &fromAddr, &fromLen);
if (nBytes < 0) {
throw std::invalid_argument("TeleRecvFrom: data length less than 0");
}
buf.resize(nBytes);
return buf;
}
// TeleSend
inline void TeleSend(const SOCKET& socket, const std::vector<char>& msg, const int32_t& flags = 0) {
int32_t _res = send(socket, msg.data(), msg.size(), flags);
if (_res == SOCKET_ERROR) {
throw std::invalid_argument("TeleSend : socket error");
}
}
// for udp sendto
// TeleSendTo
inline void TeleSendTo(const SOCKET& socket, const std::vector<char>& msg, const sockaddr& fromAddr, const int32_t& flags = 0) {
int32_t _res = sendto(socket, msg.data(), msg.size(), flags, &fromAddr, sizeof(sockaddr));
if (_res == SOCKET_ERROR) {
throw std::invalid_argument("TeleSendTo : socket error");
}
}
// command
inline std::string command(const std::vector<std::string>& cmdLst) {
std::string res;
for (auto itr = cmdLst.begin(); itr != cmdLst.end(); itr++) {
res += *itr;
if (std::next(itr) != cmdLst.end()) { res += "/"; }
}
return res;
}
// split
inline std::vector<std::string> split(const std::string& inputStr, const char& chr = '/') {
std::vector<std::string> res;
std::stringstream ss(inputStr);
std::string temp;
while (std::getline(ss, temp, chr)) {
res.push_back(temp);
}
return res;
}
inline std::string data_to_string(const std::vector<char>& data) {
return { data.begin(), data.end() };
}
inline std::string string_to_data(const std::string& str) {
return { str.begin() , str.end() };
}
} // namespace KYTinyTools
#endif
#pragma once
#ifndef __TCPIP_FUNCLITE__
#define __TCPIP_FUNCLITE__
#include "KYFuncLite.h"
namespace KYFuncLite {
// Tcp function
inline void Start_TCP_Server(Socket& sock, const std::uint16_t& Port) {
try {
sock.setSocket(Socket::Af_Inet, Socket::Stream, Socket::Normal);
auto& tcpServer = make_sockaddr(Socket::Af_Inet, htons(Port), htonl(INADDR_ANY));
sock.BindBuilder(tcpServer);
sock.ListenerBuilder(SOMAXCONN);
}
catch (const std::exception& e) {
throw e;
}
}
inline void Start_TCP_Client(Socket& sock, const std::uint16_t& R_Port, const string& IP) {
// sockaddr_in tcpClients;
try {
sock.setSocket(Socket::Af_Inet, Socket::Stream, Socket::Normal);
auto& tcpClients = make_sockaddr(Socket::Af_Inet, htons(R_Port), inet_addr(IP.c_str()));
sock.ConnectorBuilder(tcpClients);
}
catch (const std::exception& e) {
throw e;
}
}
inline void Start_UDP_Server(Socket& sock, const std::uint16_t& Port) {
try {
sock.setSocket(Socket::Af_Inet, Socket::Dgram, Socket::Normal);
auto& udpServer = make_sockaddr(Socket::Af_Inet, htons(Port), htonl(INADDR_ANY));
sock.BindBuilder(udpServer);
}
catch (const std::exception& e) {
throw e;
}
}
inline void Start_UDP_Client(Socket& sock, sockaddr& udpClient, const std::uint16_t& R_Port, const string& IP) {
try {
sock.setSocket(Socket::Af_Inet, Socket::Dgram, Socket::Normal);
}
catch (const std::exception& e) {
throw e;
}
udpClient = make_sockaddr(AF_INET, htons(R_Port), inet_addr(IP.c_str()));
}
/// ///////////////////////////////
inline Socket& TCP_Server(const std::uint16_t& Port) {
Socket sock;
try {
sock.setSocket(Socket::Af_Inet, Socket::Stream, Socket::Normal);
auto& tcpServer = make_sockaddr(Socket::Af_Inet, htons(Port), htonl(INADDR_ANY));
sock.BindBuilder(tcpServer);
sock.ListenerBuilder(SOMAXCONN);
}
catch (const std::exception& e) {
throw e;
}
return sock;
}
inline SOCKET& Fast_TCP_Server_Builder(const std::uint16_t& Port) {
SOCKET tcpSock;
WSADATA wsadata;
std::int32_t err;
sockaddr_in tcpserver;
// 1. �}�� TCP Server
if ((err = WSAStartup(0x202, &wsadata)) != 0) {
throw std::invalid_argument("WSA ERROR");
}
if ((tcpSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
throw std::invalid_argument("Socket error");
}
tcpserver.sin_family = AF_INET;
tcpserver.sin_port = htons(Port);
tcpserver.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(tcpSock, (sockaddr*)&tcpserver, sizeof(tcpserver)) < 0) {
throw std::invalid_argument("bind error");
}
if ((err = listen(tcpSock, SOMAXCONN)) < 0) {
throw std::invalid_argument("listen function error");
};
return tcpSock;
}
inline Socket& TCP_Client(const std::uint16_t& R_Port, const string& IP) {
// sockaddr_in tcpClients;
Socket sock;
try {
sock.setSocket(Socket::Af_Inet, Socket::Stream, Socket::Normal);
auto& tcpClients = make_sockaddr(Socket::Af_Inet, htons(R_Port), inet_addr(IP.c_str()));
sock.ConnectorBuilder(tcpClients);
}
catch (const std::exception& e) {
throw e;
}
return sock;
}
inline SOCKET& Fast_TCP_Client_Builder(const std::uint16_t& R_Port, const std::string& IP) {
SOCKET tcpSock;
WSADATA wsadata;
std::int32_t err;
sockaddr_in tcpclient;
if ((err = WSAStartup(0x202, &wsadata)) != 0) {
throw std::invalid_argument("WSA ERROR");
}
if ((tcpSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
throw std::invalid_argument("Socket error");
}
tcpclient.sin_family = AF_INET;
tcpclient.sin_port = htons(R_Port);
tcpclient.sin_addr.s_addr = inet_addr(IP.c_str());
if (err = connect(tcpSock, (sockaddr*)&tcpclient, sizeof(tcpclient)) < 0) {
throw std::invalid_argument("connect error");
};
return tcpSock;
}
inline Socket& UDP_Server(const WORD& Port) {
Socket sock;
try {
sock.setSocket(Socket::Af_Inet, Socket::Dgram, Socket::Normal);
auto& udpServer = make_sockaddr(Socket::Af_Inet, htons(Port), htonl(INADDR_ANY));
sock.BindBuilder(udpServer);
}
catch (const std::exception& e) {
throw e;
}
return sock;
}
inline std::pair<Socket , sockaddr>& UDP_Client(const WORD& R_Port, const string& IP) {
std::pair<Socket, sockaddr> res;
try {
res.first.setSocket(Socket::Af_Inet, Socket::Dgram, Socket::Normal);
}
catch (const std::exception& e) {
throw e;
}
res.second = make_sockaddr(AF_INET, htons(R_Port), inet_addr(IP.c_str()));
return res;
}
}
#endif // !__TCPIP_FUNCLITE__
#pragma once
// For TCPIP
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1 // �t�έn�D
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <iostream>
inline int Start_UDP_Server(SOCKET* SSock,int Port) {
// 1.�ܼƫŧi
WSADATA Wsa; // Winsock �Ѽ�
//SOCKET SSock; // �q�D�s�u�N�X
sockaddr_in Addr; // IP+Port+Protocol
// 2.�]�wWinsock/sock
int err = 0;
if (err = WSAStartup(0x202, &Wsa) != 0) { // �Ұ�Winsock
return err;
}
*SSock = socket(AF_INET, SOCK_DGRAM, 0); // �}��UDP�q�D
Addr.sin_family = AF_INET;
Addr.sin_port = htons(Port);
Addr.sin_addr.s_addr = htonl(INADDR_ANY);
// 3.�Ұ�UDP Server
bind(*SSock, (sockaddr *)&Addr, sizeof(sockaddr));
return 0;
}
inline int Start_UDP_Client(SOCKET* CSock, sockaddr* CAddr, const char* IP, int Port) {
// 1.�ܼƫŧi
WSADATA Wsa; // Winsock �Ѽ�
//SOCKET SSock; // �q�D�s�u�N�X
sockaddr_in* Addr; // IP+Port+Protocol
Addr = (sockaddr_in*)CAddr;
// 2.�]�wWinsock/sock
int err = 0;
if (err = WSAStartup(0x202, &Wsa) < 0) { // �Ұ�Winsock
return err;
}
*CSock = socket(AF_INET, SOCK_DGRAM, 0); // �}��UDP�q�D
Addr->sin_family = AF_INET;
Addr->sin_port = htons(Port);
Addr->sin_addr.s_addr = inet_addr(IP);
return 0;
}
// =======================================================================
// ================== �Ұ� TCP Server(�ϥ�thread�����s�u�P�������) ===
// =======================================================================
#include <process.h> // Project => Setting => C/C++ => Category=Code Generation => Use Runtime Library=Debug Multithreaded
SOCKET g_S_Socket, g_S_Socket1;
DWORD Thread_ID11;
// ������l�{��
VOID Thread_Func11(PVOID pvoid) {
char S1[5000];
int i, Len = sizeof(sockaddr);
sockaddr_in Addr;
while (1) {
g_S_Socket1 = accept(g_S_Socket, (sockaddr *)&Addr, &Len);
do {
i = recv(g_S_Socket1, S1, sizeof(S1) - 1, 0);
if (i > 0) {
S1[i] = 0;
printf("Recv(%s) = %s\r\n", inet_ntoa(Addr.sin_addr), S1);
}
} while (i > 0);
}
}
int Start_TCP_Server(SOCKET *psockfd, WORD Port) {
WSADATA wsadata;
int err;
struct sockaddr_in tcpserver;
// 1. �}�� TCP Server
if ((err = WSAStartup(0x202, &wsadata)) != 0) return -1;
if ((*psockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1;
tcpserver.sin_family = AF_INET;
tcpserver.sin_port = htons(Port);
tcpserver.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(*psockfd, (struct sockaddr *)&tcpserver, sizeof(tcpserver)) < 0) return -1;
if ((err = listen(*psockfd, SOMAXCONN)) < 0) return -1;
g_S_Socket = *psockfd;
// 2. �}�Ҥl�����
// Thread_ID11 = _beginthread(Thread_Func11, 0, NULL);
return 0;
}
// =======================================================================
// ================== �Ұ� TCP Client =================================
// =======================================================================
SOCKET g_C_Socket; // Global Variable
DWORD Thread_ID22;
// ������l�{��
VOID Thread_Func22(PVOID pvoid) {
char S1[2000];
int i, j, Len = sizeof(sockaddr);
sockaddr_in Addr;
BOOL Flag = 0;
int k, k1, k2, k3, Beg, End, Fa2 = 0;
char S2[2000];
while (1) {
i = recv(g_C_Socket, S1, sizeof(S1) - 1, 0);
if (i > 0) {
S1[i] = 0;
// �h�� �C�ⱱ��X(Remove Color Control Code)
for (j = 0; j < i; j++) {
if (S1[j] == 27) { // ESC
Flag = true;
Beg = j + 1;
}
if (!Flag) {
printf("%c", S1[j]);
}
if ((Flag) && (S1[j] == 'm')) {
Flag = false;
End = j;
memcpy(S2, &S1[Beg], static_cast<size_t>(End) - Beg + 1);
S2[End - Beg + 1] = 0;
k = sscanf_s(S2, "[%d;%d;%dm", &k1, &k2, &k3);
//if ((k==1)&&(k1==41))
}
}
//printf("%s",S1);
//for (i=0;i<strlen(S1);i++)
//{ if (S1[i]==0x1b) Flag=1;
// else if (S1[i]=='m') Flag=0;
// else if (Flag==0) printf("%c",S1[i]);
} //}
}
}
inline int Start_TCP_Client(SOCKET *psockfd, WORD R_Port,const char *IP) {
WSADATA wsadata;
int err;
sockaddr_in tcpclient;
if ((err = WSAStartup(0x202, &wsadata)) != 0) return -1;
if ((*psockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -1;
tcpclient.sin_family = AF_INET;
tcpclient.sin_port = htons(R_Port);
tcpclient.sin_addr.s_addr = inet_addr(IP);
if (err = connect(*psockfd, (sockaddr *)&tcpclient, sizeof(tcpclient)) < 0) return -1;
g_C_Socket = *psockfd;
// 2. �}�Ҥl�����
//Thread_ID22 = _beginthread(Thread_Func22, 0, NULL);
return 0;
}
#pragma once
#ifndef __TCPIP_THREAD_H__
#define __TCPIP_THREAD_H__
#include "KYFuncLite.h"
#include <iostream>
using std::cout;
using std::uintptr_t;
namespace KYFuncLite {
struct ServerThreadData {
Socket g_S_Socket;
Socket g_S_Socket1;
uintptr_t Thread_ID11;
} SData;
// thread
void Thread_Func11(PVOID pvoid) {
string recvData;
sockaddr_in* AddPtr;
while (1) {
try {
auto _res = SData.g_S_Socket.AcceptBuilder();
SData.g_S_Socket1.setSocket(_res.first);
AddPtr = (sockaddr_in*)&_res.second;
do {
recvData = SData.g_S_Socket1.doRecv();
if (!recvData.empty()) {
cout << "Recv (" << inet_ntoa(AddPtr->sin_addr) << ") = " << recvData << '\n';
}
} while (recvData.size() > 0);
}
catch (const std::exception& e) {
// pass
}
}
}
struct ClientThreadData {
Socket g_C_Socket;
uintptr_t Thread_ID22;
} CData;
void Thread_Func22(PVOID pvoid) {
string _res , _resClone;
bool Flag = false;
int k, k1, k2, k3, Beg, Fa2 = 0;
while (1) {
_res = CData.g_C_Socket.doRecv();
if (!_res.empty()) {
for (size_t i = 0; i < _res.size(); i++) {
if (_res[i] == 27) {
Flag = true;
Beg = i + 1;
}
if (!Flag) {
cout << _res[i];
}
if ((Flag) && (_res[i] == 'm')) {
Flag = false;
_resClone = string(_res.begin() + Beg, _res.begin() + (i - Beg));
// S2[End - Beg + 1] = 0;
k = sscanf_s(_resClone.c_str(), "[%d;%d;%dm", &k1, &k2, &k3);
//if ((k==1)&&(k1==41))
}
}
}
}
}
}
#endif // !__TCPIP_THREAD_H__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment