int CSessionThread::Send(struct packet_s& out_pkt) { CSingleLock GateKeeper(&m_ImmediateSendAccess, TRUE); int retcode, len; len = BufferLength(out_pkt); if (len < sizeof(out_pkt.header)) len = sizeof(out_pkt.header); out_pkt.header.magic = htonl(PKT_MAGIC_NUMBER); out_pkt.header.size = htons(len); out_pkt.header.sequence = htonl(++m_sent_packets); retcode = send(m_socket, (LPSTR)&out_pkt, len, 0); m_bytes_sent += len; if (retcode == SOCKET_ERROR) { retcode = 0; if (WSAGetLastError() == WSAECONNRESET) // Conexão abortada { m_stop = TRUE; } else { ReportSocketError(__LINE__); } } return retcode; }
/// 创建socket bool ConnectServer(const char * ip, unsigned short port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = inet_addr(ip); if (connect(m_handle, (struct sockaddr *)&addr, sizeof(addr)) < 0) { ReportSocketError("connect"); return false; } return true; }
/// 读数据 virtual void HandleRead() { memset(g_read_buffer, 0, kBufferSize); int len = recv(m_handle, g_read_buffer, kBufferSize, 0); if (len > 0) { fprintf(stderr, "%s", g_read_buffer); g_reactor.RegisterHandler(this, reactor::kWriteEvent); } else { ReportSocketError("recv"); } }
/// 写数据 virtual void HandleWrite() { memset(g_write_buffer, 0, kBufferSize); int len = sprintf(g_write_buffer, "time\r\n"); len = send(m_handle, g_write_buffer, len, 0); if (len > 0) { fprintf(stderr, "%s", g_write_buffer); g_reactor.RegisterHandler(this, reactor::kReadEvent); } else { ReportSocketError("send"); } }
void CSessionThread::CloseSession() { CSingleLock Closing(&m_SessionCloserGateKeeper, TRUE); AddEvent(EVENT_SENT, 0, _T("Encerrando fila de saída")); CSingleLock LockSender(&m_SenderGateKeeper, TRUE); AddEvent(EVENT_SENT, 0, _T("Encerrando processador de pedidos")); CSingleLock LockDispatcher(&m_DispatcherGateKeeper, TRUE); EmptyAllLists(); if (m_open) { m_open = FALSE; if (closesocket(m_socket) == SOCKET_ERROR) // Any doubt dbItens will be closed? { ReportSocketError(__LINE__); } AddEvent(EVENT_SENT|EVENT_RECEIVED, 0, _T("Sessão encerrada!")); m_timeSessionEnd = CTime::GetCurrentTime(); } }
int CSessionThread::Receive(struct packet_s& pkt) { int retcode; char *buffer = m_input_buffer; // Yes, I'm lazy! int offset = m_input_buffer_offset; struct packet_s *pktx = (struct packet_s *)buffer; // to help debugging //AddEvent(EVENT_SENT, 0, _T("Offset = %ld"), (LONG)offset); while (offset < ntohs(pktx->header.size) /*- 1*/ || ntohl(pktx->header.magic) != PKT_MAGIC_NUMBER) { //AddEvent(EVENT_SENT, 0, _T("recv - Offset = %ld"), (LONG)offset); retcode = recv(m_socket, buffer+offset, RECEIVE_BUFFER_SIZE - offset/*sizeof pkt*/, 0); if (retcode == SOCKET_ERROR) { retcode = 0; if (WSAGetLastError() == WSAECONNRESET) // Conexão abortada { m_stop = TRUE; } else { ReportSocketError(__LINE__); return 0; } } else { offset += retcode; while (offset >= sizeof(pkt.header.magic) /*- 1*/) { if (ntohl(pktx->header.magic) == PKT_MAGIC_NUMBER) { break; } else { char *source = buffer + 1; char *target = buffer; int move = --offset; while (move--) *(target++) = *(source++); } } } } // AddEvent(EVENT_SENT, 0, _T("recv - Size = %ld"), (LONG)ntohs(pktx->header.size)); //if (retcode > 0) if (offset >= ntohs(pktx->header.size) /*- 1*/) { int size = ntohs(pktx->header.size); ClearBuffer(pkt); memcpy(&pkt, buffer, size); offset -= size; // move rest of buffer to its beggining if (offset >= 0) { int residue = offset; char *source = buffer + size; while (residue--) *(buffer++) = *(source++); } else { AddEvent(EVENT_RECEIVED, 0, _T("Offset < 0!!!")); offset = 0; } retcode = size; } if (retcode < 0) { retcode = 0; } else { m_bytes_received += retcode; if (++m_received_packets != ntohl(pkt.header.sequence)) { AddEvent(EVENT_RECEIVED, 0, _T("ALERTA! RCV=%ld SEQ=%ld"), m_received_packets, ntohl(pkt.header.sequence)); m_received_packets = ntohl(pkt.header.sequence); } } m_input_buffer_offset = offset; // give dbItens back return retcode; }
BOOL CSessionThread::Open(void) { m_sent_packets = m_received_packets = 0; m_bytes_received = m_bytes_sent = 0; m_sender_thread_instances = m_receiver_thread_instances = m_dispatcher_thread_instances = 0; m_ReceivedEventsGateKeeper.Lock(); m_events_received.RemoveAll(); m_ReceivedEventsGateKeeper.Unlock(); m_SentEventsGateKeeper.Lock(); m_events_sent.RemoveAll(); m_SentEventsGateKeeper.Unlock(); EmptyAllLists(); { WSADATA wsadata; int nRc = WSAStartup(0x0101, &wsadata); if (nRc) { ReportSocketError(__LINE__); return FALSE; } } sockaddr_in addr; m_socket = socket(AF_INET, SOCK_STREAM, 0); if (m_socket == INVALID_SOCKET) { ReportSocketError(__LINE__); return FALSE; } addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(m_socket, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) { ReportSocketError(__LINE__); CloseSession(); return FALSE; } else { sockaddr_in saddr; CPedidosRegistry Reg; saddr.sin_family = AF_INET; saddr.sin_port = htons((unsigned short)Reg.GetDWord(_T("Porta"))); { char sz[32]; saddr.sin_addr.s_addr = inet_addr(CString2sz(sz, Reg.GetString(_T("Servidor")))); } if (connect(m_socket, (LPSOCKADDR)&saddr, sizeof(saddr)) == SOCKET_ERROR) { ReportSocketError(__LINE__); CloseSession(); return FALSE; } else { struct packet_s in_pkt, out_pkt; m_timeSessionStart = CTime::GetCurrentTime(); // Aguarda solicitacao de versao do { if (!Receive(in_pkt)) return FALSE; } while (ntohs(in_pkt.header.type) != PKT_ASK_VERSION && !m_stop); // Envia versao ClearBuffer(out_pkt); out_pkt.header.type = htons(PKT_SND_VERSION); out_pkt.version.number = htons(PROTOCOL_VERSION); if (!Send(out_pkt)) { CloseSession(); return FALSE; } // Aguarda solicitacao de logon if (!Receive(in_pkt)) return FALSE; if (ntohs(in_pkt.header.type) != PKT_ASK_LOGON) { AddEvent(EVENT_RECEIVED, 0, _T("Falha de protocolo")); CloseSession(); return FALSE; } // Envia logon ClearBuffer(out_pkt); out_pkt.header.type = htons(PKT_SND_LOGON); out_pkt.logon.codigo_vendedor = htons((WORD)Reg.GetDWord(_T("VendedorCodigo"))); CString2sz(out_pkt.logon.senha, Reg.GetString(_T("VendedorSenha"))); if (!Send(out_pkt)) { CloseSession(); return FALSE; } // Aguarda confirmacao da senha if (!Receive(in_pkt)) { CloseSession(); return FALSE; } if (ntohs(in_pkt.header.type) != PKT_ACK_LOGON) { AddEvent(EVENT_RECEIVED, 0, _T("Erro: Código ou senha inválidos!")); CloseSession(); return FALSE; } // Debug sequence /* for (int i = 0; i < 10; i++) { ClearBuffer(out_pkt); strcpy(out_pkt.cliente.endereco_cobranca.cep, "98765-432"); out_pkt.header.type = htons(PKT_ACK_VERSION); Send(out_pkt); } */ m_open = TRUE; m_SessionThread = AfxBeginThread(SessionThreadStart, this); AddEvent(EVENT_SENT|EVENT_RECEIVED, 0, _T("Sessão iniciada!")); } } return TRUE; }