Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In my VC++ code, there are two client and server program.

Client program send Command_info to the server program.
Server program send reply packet as same as Command_info.

But I change value of one field of Command_info, the client makes exception runtime error like as follows.

The Client sources are:

C++
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;
		}
	}
}

In the above client program,
Anythings are ok if I set the value of Cmd.net = 1.
I receive from the server and Cmd.rep_type is "REPLY_OK".

But when I change the value Cmd.net = 2,
I have no problem to receive from the server. But after showing AfxMessageBox(_T("OK")), there are many runtime error messages including "access violation error" and finding "memcpy.asm source" - that is my first experience of runtime messages.

Who knows the cause and how to fix?

// So you can the code of 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: I tried to change this protocol from TCP/IP to file io between Client and Server, but failed.
At the same point and same runtime error messages are displayed.

What I have tried:

More 1 week wasted for this problem.
Posted
Updated 25-Aug-17 2:07am
v5
Comments
Jochen Arndt 25-Aug-17 2:55am    
The error is most likely not in the code shown (it looks OK). It might be located in the sending or (more probable) receiving function.

An access violations occurs when writing to memory that is not owned by the application. Typical sources are invalid pointers or array indexes that are out of bound. The latter will overwrite other memory which might lead to access violations when that memory contains pointers.

You might update your question with the TCPClientRecv() code.
Richard MacCutchan 25-Aug-17 3:21am    
With all those goto statements it is difficult to be certain, but you may well be missing a pointer initialisation. The only way to diagnose this is to use your debugger to trace through the code to the point of the first error.

C++
else {
    TRACE(("TCP Data %d bytes received.\n"), TRecv_Size);
    ::ZeroMemory(&Cmd, sizeof(Cmd));
    memcpy(&Cmd, TRecvBuffer, TRecv_Size);
    return RESULT_SUCCESS;
}

Where is Cmd defined in the TCPClientRecv process, and is it big enough to contain everything copied from the TRecvBuffer ?
 
Share this answer
 
Your code does not show the relevant declarations for the used variables. You should avoid using global variables (the plain function name TCPClientRecv() indicates that this is not a class member function).

Even if that is a class member function you should use function local variables instead of class member variables where possible.

An example is your TRecvBuffer. How is that declared (with which size)? The TBUFFER_SIZE definition is located within the function but the variable seems to be declared outside (on top of source file or in a header file) so that it can not use the that definition. Because the buffer is only used within the function, it is a candidate for a function local variable.

You are defining struct Command_info and declare the local Cmd variable in your SendData2SS function. How can the TCPClientRecv() function then access that variable? To do that it has to be passed as argument or variable and the function must be class members.

To nail it done:
The code presented here would not even compile. If you expect help you have to show the code exactly as it is. If you have to cut code snippets, you must provide all information about the snippet that is necessary to reproduce what is done. This applies especially to the declarations of the used variables and handling of dynamically allocated variables.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900