#include "stdafx.h" #include "TCPSocket.h" #include #include #include #include "log4z.h" #include "LogInit.h" #include LogInit _loginti; WinSocketSystem _winsocket_init; TCPServer::TCPServer() { m_pNotify = NULL; sockSrv = INVALID_SOCKET; sockCli = INVALID_SOCKET; } TCPServer::~TCPServer() { Stop(); } int TCPServer::InitNet(const char*ip, int port, INetNotify*pNotify) { m_pNotify = pNotify; SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);//Auto IP, byte sequence change addrSrv.sin_port = htons(port); sockSrv = socket(AF_INET, SOCK_STREAM, 0); if (sockSrv == INVALID_SOCKET){ LOGFMTE("create socket error errorno=%d", WSAGetLastError()); return -2; } // 绑定 int err = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); if (err != 0){ LOGFMTE("bind error errorno=%d", WSAGetLastError()); return -3; } // 监听 err = listen(sockSrv, 5); if (err != 0){ LOGFMTE("listen error errorno=%d", WSAGetLastError()); return -4; } // 启动监听线程 _listen_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPServer::ListenThread, this, 0, NULL); LOGI("服务端启动监听成功"); return 0; } int TCPServer::SendData(const char*data) { if (sockCli == INVALID_SOCKET){ return -1;// 没有链接 } char header[16] = { 0 }; int data_size = strlen(data); std::string str_data = data; sprintf_s(header, "%12d", data_size); int nLen = 0; AutoLock _lck(m_tx_send); do { int send_tmp_ = send(sockCli, header + nLen, 12 - nLen, 0); if (send_tmp_ == SOCKET_ERROR){ closesocket(sockCli); sockCli = INVALID_SOCKET; return -2; } else{ nLen += send_tmp_; } } while (nLen < 12); nLen = 0; do { int send_tmp_ = send(sockCli, data + nLen, data_size - nLen, 0); if (send_tmp_ == SOCKET_ERROR){ int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ closesocket(sockCli); sockCli = INVALID_SOCKET; return -2; } } else{ nLen += send_tmp_; } } while (nLen < data_size); return 0; } unsigned TCPServer::ListenThread(void *param) { TCPServer*pThis = static_cast(param); LOGI("启动监听线程"); SOCKADDR_IN addrClt; int len = sizeof(SOCKADDR); while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE) && pThis->sockSrv != INVALID_SOCKET){ SOCKET sockCon = accept(pThis->sockSrv, (SOCKADDR*)&addrClt, &len); if (sockCon == INVALID_SOCKET){ continue; } else{ if (pThis->sockCli != sockCon){ if (pThis->sockCli != INVALID_SOCKET){ closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET; if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"cmd\":\"socket_switch\"}"); } // 新的链接 pThis->sockCli = sockCon; if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"cmd\":\"new_connect\"}"); } ::InterlockedExchange((PLONG)&pThis->m_bexit, TRUE); ::WaitForSingleObject(pThis->_recv_thread, INFINITE); ::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE); // 启动接受线程 pThis->_recv_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPServer::RecvThread, param, 0, NULL); } } LOGI("退出监听线程"); return 0; } unsigned TCPServer::RecvThread(void *param) { TCPServer*pThis = static_cast(param); while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE) && pThis->sockSrv != INVALID_SOCKET){ if (pThis->sockCli != INVALID_SOCKET){ // 接收头部10字节 char header[16] = { 0 }; int nLen = 0; do { int tmp_len = 0; tmp_len = recv(pThis->sockCli, header + nLen, 12 - nLen, 0); if (tmp_len == 0) {// 链接关闭 LOGE("关闭连接"); if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}"); closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET; return 0; } else if (tmp_len == SOCKET_ERROR){ // 出错 int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ LOGE("出错-关闭连接"); closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET; if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}"); return 0; } } nLen += tmp_len; } while (nLen<12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)); LOGFMTI("接受头部信息:%s", header); if (strlen(header) == 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){ int data_size = atoi(header); char *rcv_buf = new char[data_size + 1]; memset(rcv_buf, 0, data_size + 1); nLen = 0; do { int tmp_len = 0; tmp_len = recv(pThis->sockCli, rcv_buf + nLen, data_size - nLen, 0); if (tmp_len == 0) {// 链接关闭 if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}"); closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET; delete[] rcv_buf; rcv_buf = NULL; return 0; } else if (tmp_len == SOCKET_ERROR){ // 出错 int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET; if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}"); delete[] rcv_buf; rcv_buf = NULL; return 0; } } nLen += tmp_len; } while (nLen < data_size&&!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)); LOGFMTI("接受信息:%s", rcv_buf); if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify(rcv_buf); delete[] rcv_buf; rcv_buf = NULL; } else{ LOGFMTE("头部长度错误:%d, header=%s", strlen(header), header); } } } return 0; } void TCPServer::Stop() { LOGI("主动停止监听"); if (sockSrv != INVALID_SOCKET){ closesocket(sockSrv); sockSrv = INVALID_SOCKET; } if (sockCli != INVALID_SOCKET){ closesocket(sockCli); sockCli = INVALID_SOCKET; } ::InterlockedExchange((PLONG)&m_bexit, TRUE); WaitForSingleObject(_listen_thread, INFINITE); WaitForSingleObject(_recv_thread, INFINITE); } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// TCPClient::TCPClient() { m_connected = FALSE; m_pNotify = NULL; } TCPClient::~TCPClient() { Stop(); m_pNotify = NULL; } int TCPClient::InitNet(const char*ip, int port, INetNotify*pNotify) { m_pNotify = pNotify; sockConn = socket(AF_INET, SOCK_STREAM, 0); if (sockConn == INVALID_SOCKET){ LOGE("create socket error"); return -2; } SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.s_addr = inet_addr(ip); addrSrv.sin_port = htons(port); int err = connect(sockConn, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); if (err == INVALID_SOCKET){ LOGE("connect server error"); return -3; } ::InterlockedExchange((PLONG)&m_connected, TRUE); _loop_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPClient::LoopThread, this, 0, NULL); LOGI("连接成功-启动接受线程 LoopThread"); return 0; } void TCPClient::Stop() { if (sockConn != INVALID_SOCKET){ closesocket(sockConn); sockConn = INVALID_SOCKET; } ::InterlockedExchange((PLONG)&m_bexit, TRUE); ::WaitForSingleObject(_loop_thread, INFINITE); } int TCPClient::SendData(const char*data) { if (!m_connected){ return -1;//未连接 } if (sockConn == INVALID_SOCKET){ return -2; } char header[16] = { 0 }; int data_size = strlen(data); std::string str_data = data; sprintf_s(header, "%12d", data_size); int nLen = 0; AutoLock _lck(m_tx_send); do { int send_tmp_ = send(sockConn, header + nLen, 12 - nLen, 0); if (send_tmp_ == SOCKET_ERROR){ int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ closesocket(sockConn); sockConn = INVALID_SOCKET; return -3; } } else{ nLen += send_tmp_; } } while (nLen < 12); nLen = 0; do { int send_tmp_ = send(sockConn, data + nLen, data_size - nLen, 0); if (send_tmp_ == SOCKET_ERROR){ int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ closesocket(sockConn); sockConn = INVALID_SOCKET; return -3; } } else{ nLen += send_tmp_; } } while (nLen < data_size); return 0; } unsigned int TCPClient::LoopThread(PVOID param) { TCPClient*pThis = static_cast(param); while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){ if (pThis->sockConn != INVALID_SOCKET){ // 接收头部12字节 char header[16] = { 0 }; int nLen = 0; do { int tmp_len = 0; tmp_len = recv(pThis->sockConn, header + nLen, 12 - nLen, 0); if (tmp_len == 0) {// 链接关闭 LOGE("关闭连接"); if (pThis->m_pNotify){ pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_close\"}"); } closesocket(pThis->sockConn); pThis->sockConn = INVALID_SOCKET; return 0; } else if (tmp_len == SOCKET_ERROR){ // 出错 int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ LOGE("出错-关闭连接"); closesocket(pThis->sockConn); pThis->sockConn = INVALID_SOCKET; if (pThis->m_pNotify){ pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_error\"}"); } return 0; } } nLen += tmp_len; } while (nLen < 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)); LOGFMTI("接收头部信息:%s", header); if (strlen(header) == 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){ int data_size = atoi(header); char *rcv_buf = new char[data_size + 1]; memset(rcv_buf, 0, data_size + 1); nLen = 0; do { int tmp_len = 0; tmp_len = recv(pThis->sockConn, rcv_buf + nLen, data_size - nLen, 0); if (tmp_len == 0) {// 链接关闭 if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_close\"}"); closesocket(pThis->sockConn); pThis->sockConn = INVALID_SOCKET; delete[] rcv_buf; rcv_buf = NULL; return 0; } else if (tmp_len == SOCKET_ERROR){ // 出错 int last_error = WSAGetLastError(); if (last_error == WSAEWOULDBLOCK){ continue; } else{ closesocket(pThis->sockConn); pThis->sockConn = INVALID_SOCKET; if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_error\"}"); delete[] rcv_buf; rcv_buf = NULL; } return 0; } nLen += tmp_len; } while (nLen < data_size&&!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)); LOGFMTI("接收信息:%s", rcv_buf); if (pThis->m_pNotify) pThis->m_pNotify->OnNetNotify(rcv_buf); delete[] rcv_buf; rcv_buf = NULL; } else{ LOGFMTE("头部长度错误:%d, header=%s", strlen(header), header); } } } return 0; } TCPClient* g_cli = NULL; TCPServer* g_srv = NULL; int NetOperator::InitServer(const char*ip, int port, INetNotify*pNotify) { if (g_srv != NULL){ return -1;// 服务器已经启动 } g_srv = new TCPServer; int nRet = g_srv->InitNet(ip, port, pNotify); if (nRet<0){ delete g_srv; g_srv = NULL; } return nRet; } int NetOperator::InitClient(const char*ip, int port, INetNotify*pNotify) { if (g_cli != NULL){ return -1;// client已经启动 } g_cli = new TCPClient; int nRet = g_cli->InitNet(ip, port, pNotify); if (nRet <0){ delete g_cli; g_cli = NULL; } return nRet; } void NetOperator::SetServerNotifyPtr(INetNotify*pNotify) { if (g_srv) g_srv->SetNotify(pNotify); } void NetOperator::SetClientNotifyPtr(INetNotify*pNotify) { if (g_cli) g_cli->SetNotify(pNotify); } void NetOperator::ServerStop() { if (g_srv){ g_srv->Stop(); delete g_srv; g_srv = NULL; } } int NetOperator::ServerSendData(const char*data) { int ret = -1; if (g_srv){ ret = g_srv->SendData(data); } return ret; } void NetOperator::ClientStop() { if (g_cli){ g_cli->Stop(); delete g_cli; g_cli = NULL; } } int NetOperator::ClientSendData(const char*data) { int ret = -1; if (g_cli){ ret = g_cli->SendData(data); } return ret; }