Как я могу решить свою простую или непростую проблему?
В моем коде VC++ есть две клиентские и серверные программы.
Клиентская программа отправляет Command_info в серверную программу.
Серверная программа отправляет ответный пакет так же, как и Command_info.
Но я могу изменить значение одного поля из Command_info, клиент делает исключения ошибки во время выполнения, такие как в следующем.
Клиентскими источниками являются:
void CForm2000::SendData2SS(int control_code, int net, int input_value, int output_value) { struct Command_info { int control_code; int network; int rep_type; unsigned int input_value; unsigned int output_value; int error_code; }; Command_info Cmd; Cmd.control_code = control_code; if (net == 0) net = MY_Type; Cmd.network = net; Cmd.rep_type = REP_REQ; Cmd.input_value = input_value; Cmd.output_value = output_value; Cmd.error_code = 0; int SendSW = 0; while (TcpConnectStatus == 0) TCPClientOpen(); while (TcpConnectStatus == 1) { if (SendSW == 0) { int retcode = TCPClientSend(); if (retcode == RESULT_SUCCESS) SendSW = 1; } if (SendSW == 1) { if (TCPClientRecv() == RESULT_SUCCESS) { if (Cmd.rep_type == REPLY_OK) { if (Cmd.error_code == 0) AfxMessageBox(_T("OK")); else AfxMessageBox(_T("Not OK")); } } else AfxMessageBox(_T("Communication Error")); return; } } }
В приведенной выше клиентской программе,
Все в порядке, если я установлю значение Cmd.net = 1.
Я получаю от сервера и Cmd.rep_type является "REPLY_OK".
Но когда я изменяю значение Cmd.net = 2,
У меня нет никаких проблем с получением от сервера. Но после показа AfxMessageBox (_T ("OK")) появляется много сообщений об ошибках времени выполнения, включая" ошибку нарушения доступа "и поиск" источника memcpy.asm " - это мой первый опыт работы с сообщениями времени выполнения.
Кто знает причину и как ее исправить?
// Таким образом, вы можете использовать код TCPClientRecv()
int TCPClientRecv() { #define TBUFFER_SIZE 1024 int ret_code = RESULT_FAIL; int error_cnt = 0; int retcnt = 0; while (TCP_WORKING_SW == 1) { TRACE("TCP SOCKET try to recving, RetryCnt = %d\n", ++retcnt); ::ZeroMemory(TRecvBuffer, TBUFFER_SIZE); TRecv_Size = recvfrom(ClientSocket, TRecvBuffer, TBUFFER_SIZE, 0, (struct sockaddr*) &ToServer, &ToServer_Size); if ((TCP_WORKING_SW == 0)) goto EXIT; if (TRecv_Size <= 0) { if (TRecv_Size == -1) { if (error_cnt++ > 100) goto EXIT; Sleep(100); int ret_code = WSAGetLastError(); if (ret_code == WSAEWOULDBLOCK) ; else if (ret_code == WSAECONNABORTED) goto EXIT; else if (ret_code == WSAENOTCONN) TCPClientOpen(); else goto EXIT; } else if (TRecv_Size == 0) { ret_code = RESULT_RESET; goto EXIT; } else { TRACE("recvfrom() error. Closing SOCKET. TRecv_Size = %d \n", TRecv_Size); goto EXIT; } } else { TRACE(("TCP Data %d bytes received.\n"), TRecv_Size); ::ZeroMemory(&Cmd, sizeof(Cmd)); memcpy(&Cmd, TRecvBuffer, TRecv_Size); return RESULT_SUCCESS; } } EXIT: TCPClientClose(); ErrorCode = E_SOCKET_RECEIVE; return ret_code; }//int TCPClientRecv()
PS: Я попытался изменить этот протокол с TCP / IP на файловый ввод-вывод между клиентом и сервером, но потерпел неудачу.
В той же точке и те же сообщения об ошибках во время выполнения отображаются.
Что я уже пробовал:
Еще 1 неделя потрачена впустую на эту проблему.
Jochen Arndt
Ошибка, скорее всего, не в показанном коде (он выглядит нормально). Он может быть расположен в отправляющей или (что более вероятно) принимающей функции.
Нарушение доступа происходит при записи в память, которая не принадлежит приложению. Типичными источниками являются недопустимые указатели или индексы массивов, которые не привязаны. Последний будет перезаписывать другую память, что может привести к нарушениям доступа, когда эта память содержит указатели.
Вы можете обновить свой вопрос с помощью кода TCPClientRecv ().
Richard MacCutchan
Со всеми этими операторами goto трудно быть уверенным, но вы вполне можете пропустить инициализацию указателя. Единственный способ диагностировать это - использовать отладчик для отслеживания кода до точки первой ошибки.