Connection reset by peer (tcp_socket)

Hello,

I communicate between my card and my server due to interrupt function. When my client (card RABBIT BL4S100) use the button, I create a socket between my server and my client to receive the state of my client. My problem is : after my first “while”, I receive during the second reconnection : connection reset by peer.

To have a reconnection i used it :


 if (button_event)
      {
         // See if button message is not currently displayed
         if (digIn(3) !=0)
         {
            char buffer[2048];
   	 		int bytes_read;
 	  		   longword  destIP;
  				tcp_Socket socket;
 	  			int digIn();

   //création de la socket
   sock_init();
	while (ifpending(IF_DEFAULT) == IF_COMING_UP) {
	tcp_tick(NULL);
	}

	if( 0L == (destIP = resolve(DEST)) ) {
		printf( "ERROR: Cannot resolve \"%s\" into an IP address
", DEST );
		exit(2);
	}

	tcp_open(&socket,0,destIP,PORT,NULL);

	printf("Waiting for connection...
");
	while(!sock_established(&socket) && sock_bytesready(&socket)==-1) {
		tcp_tick(NULL);
	}

	printf("Connection established, sending request...
");


	/*
	 *  When tcp_tick()-ing on a specific socket, we get non-zero return while
	 *  it is active, and zero when it is closed (as used here).
	 */

	sock_write(&socket,"client actif 
",30);

  	do {
		bytes_read=sock_fastread(&socket,buffer,sizeof(buffer)-1);

		if(bytes_read>0) {
			buffer[bytes_read] = '\0';
			/*
			 * By using the "%s" format, if there are "%" in the buffer, printf()
			 *  won't try to interpret them!
			 */
			printf("%s",buffer);
		}
	}

  while(!tcp_tick(&socket));  //here it's my problem. I used "!" to close my socket because the condition isn't fulfilled else.

	sock_abort(&socket);
	printf("
Connection closed...
");

   }

I think i don’t close correctly my socket here because normally my socket will must closed due to my server but this doesn’t work :

My server is like it :


int main (int argc, char **argv) {
    int socket_desc;
    int new_socket;
    int n, pid;
    char buffer[256];
    struct sockaddr_in server;
    struct sockaddr_in client;

    // creation du socket
    socket_desc = socket(AF_INET, SOCK_STREAM, 0);

    if (socket_desc == -1) {
        perror("ERROR opening socket");
        exit(1);
    }

    // initialisation des membres de l'objet server
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8888);

    // bind
    if (bind(socket_desc, (struct sockaddr * )&server, sizeof(server)) < 0) {
        perror("ERROR on binding");
        exit(1);
    }
    printf("
bind done
");

    // sleep mode en attendant un client
    listen(socket_desc, 3);
    printf("
waiting for incoming connections...
");

    n = sizeof(struct sockaddr_in);

    // boucle infinie qui accepte et fork les clients distant
    while(1) {
        new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &n);

        if (new_socket < 0) {
            perror("ERROR on accept");
            exit(1);
        }

        // affiche les infos du client
        printf("Connection from %s:%d accepted
", 
            inet_ntoa(client.sin_addr), // conversion adr en un format Inet Std dot Ntation (str)
            ntohs(client.sin_port)); // conversion Network Byte Order vers Host Byte Order (endianess)
            
        // creation process enfant
        pid = fork();

        if (pid < 0) {
            perror("ERROR on fork");
            exit(1);
        }

        if (pid == 0) {
            // processus du client
            close(socket_desc);
            childProcess(new_socket);
            exit(0);
        }
        else {
            close(new_socket);
        }
    }
    return 0;
}

I don’t understand why my socket isn’t close after my answer of my client on the state. (I have tried many things like sock_close, sock_shutdown (but doesn’t work on dynamic C). But i can’t correctly close my client on my server to avoid this problem.

A few thing to try/consider.

First, the formatting for a do/while loop is:


do {
  // statements
} while (condition);

Your placement of the while on its own line makes me think you are forgetting it it a part of the do loop above.

Second, your comment of “here it’s my problem. I used “!” to close my socket because the condition isn’t fulfilled else” does not make sense. Adding a “!” just negates the return value of tcp_tick().

But the biggest problem is that you’re declaring your tcp_Socket on the stack of a function. Move that declaration outside of the functions so it’s declared as a global, or add “static” to the declaration so it survives beyond the life of your function. If this is your main() function, it might not matter, but you need to make sure that if any other code calls tcp_tick() (like another task or costate) your tcp_Socket structure is available.

I’m having trouble reading your code because of the mixed space/tab indentation, but you need to make sure that you’re calling tcp_tick() periodically, even if you don’t have any sockets open.

Ultimately what are you trying to do with this program? You may need to redesign it somewhat so you have a main loop that always calls tcp_tick(), and then check for some condition that opens a socket. And if the socket is already open, check for the condition that should close the socket.

Hello TomCollins, Thank you for theses answers. To beginning my do / while is correct ( there is a if before that’s why you can be confused by “{{”.

For the second problem, i’m agree with you. It’s was just to close my connection but it was usuless (my connection closes correctly now).

Your biggest problem is my biggest problem too. For you, i need to declare my tcp_socket on the stack of a function. My problem was to close my host during my condition of the interruption to resolve this I decided to open and close my socket during my condition : “if” “else”.

But for my next step I must implement this function with multitasking (little hard for me who beggin). To Implement my function I have take the example costate but I have many problems :

1/ How I open my client ?

I have tried this :

cofunc int basic_tcp[2](tcp_Socket *s, int port, char *buf){
auto int length, space_avaliable;

if( 0L == (destIP = resolve(DEST)) ) {
	printf( "ERROR: Cannot resolve \"%s\" into an IP address

", DEST );
exit(2);
}

tcp_open(&socket,0,destIP,PORT,NULL);

// wait for a connection
while(!sock_established(&socket) && sock_bytesready(&socket)==-1) {
tcp_tick(NULL);
}

// give other tasks time to do things while we are waiting
yield;
while(sock_established(s)) {
space_avaliable = sock_tbleft(s);

// limit transfer size to MAX_BUFSIZE, leave room for '\0'
if(space_avaliable > (MAX_BUFSIZE-1))
space_avaliable = (MAX_BUFSIZE-1);

// get some data
length = sock_fastread(s, buf, space_avaliable);
if(length > 0) { // did we receive any data?
buf[length] = '\0'; // print it to the Stdio window
printf("%s",buf);

// send it back out to the user's telnet session
// sock_fastwrite will work-we verified the space beforehand
sock_fastwrite(s, buf, length);
  					}
	yield; // give other tasks time to run
}

sock_close(s);
return 1;
}

But destIP isn’t declared with cofunc.

My second problem is : Where i must implement my interruption and my condition. Because i have tried to use primary part of my interruption but this function doesn’t work :

root void button_press()
{
// Save time of button press and set event flag
time_stamp = MS_TIMER;
button_event = 1;

// Turn off all interrupt flags serviced by this handler
/**Beginheader RSB_CLEAR_ALL_IRQ/
RSB_CLEAR_ALL_IRQ(bp_handle);
/**Endheader RSB_CLEAR_ALL_IRQ/
}

As you see i have tried Beginheader / end but they don’t work probably because i don’t have any ending and it’s really strange to use it.

And my last problem is your calling tcp_tick() ? tcp-tick is a single kernel routine designed to quickly process packets and return as soon as possible so if he used in a costate i don’t need to use it again ?

You might not need to use cofunctions. Take a look at Samples/tcpip/MULTI_ECHO.C for code that supports multiple sockets.

BeginHeader/EndHeader comments are only necessary for libraries.

Maybe look to other samples for code to check for button presses. You probably don’t need to use interrupts for that. Just have a big loop in main() that checks buttons, advances the state of TCP sockets, and calls tcp_tick(). The MULTI_ECHO.C sample may be a good starting point for that.

Are you building this into a product, or is this just a learning experience for you? If a product, you might want to hire a more experienced developer to do the initial coding for you, and then you can tweak it as needed.

Hello Collins,

It’s just learning experience for me during an intership but i don’t have many help so i try ^^, ! ty for theses answers. I have somes conditions like need interruption, my server use multithread so i must include this in my client (card rabbit) that’s why i need to use costate/ cofunction ect… Actully i have a interruption function who works ( but need a loop) and implement this with multitasking.

i have discover this maybe more pratical for multitasking than costate :
// 1. Explicitly use µC/OS-II library
#use “ucos2.lib”
void RandomNumberTask(void pdata);
// 2. Declare semaphore global so all tasks have access
OS_EVENT
RandomSem;
void main(){
int i;
// 3. Initialize OS internals
OSInit();
for(i = 0; i < OS_MAX_TASKS; i++)
// 4. Create each of the system tasks
OSTaskCreate(RandomNumberTask, NULL, 512, i);
// 5. semaphore to control access to random number generator
RandomSem = OSSemCreate(1);
// 6. Begin multitasking
OSStart();
}
void RandomNumberTask(void *pdata)
{
OS_TCB data;
INT8U err;
INT16U RNum;
OSTaskQuery(OS_PRIO_SELF, &data);
while(1)
{
// Rand is not reentrant, so access must be controlled via a semaphore.
OSSemPend(RandomSem, 0, &err);
RNum = (int)(rand() * 100);
OSSemPost(RandomSem);
printf("Task%d’s random #: %d
",data.OSTCBPrio,RNum);
// Wait 3 seconds in order to view output from each task.
OSTimeDlySec(3);
}
}

just need to understand how define my task with my creation socket + interrupt and will be fine i think.