Comment se fait-il que lorsqu'un thread se termine, le processus parent se termine également ? Lorsque je lance le serveur, tout va bien. Il est assis et écoute sur le socket. Lorsqu'un client se connecte, le serveur s'exécute pour le servir. Lorsqu'ils discutent, le client quitte le processus et le serveur quitte également le processus. J'utilise pthread.h pour le threading. Les voici !
D'abord le client :
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#define CLIENT_CONNECTED 0
#define CLIENT_NOT_CONNECTED 1
#define PORT 9999
#define MAX_CLIENTS 100
using namespace std;
struct client {
int socket;
int state;
pthread_t tid;
};
int
connectToServer (char *address )
{
struct hostent *hostinfo;
struct sockaddr_in name;
int s;
int rc = 0;
if ( ( s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
cerr<<"Client could not declare socket"<<"\n";
exit( 1 );
}
name.sin_family = AF_INET;
name.sin_port = htons ( ( unsigned short int ) PORT );
name.sin_addr.s_addr = htonl( INADDR_ANY );
hostinfo = gethostbyname ( address );
if ( hostinfo == NULL )
{
cerr<<"Host unknown"<<"\n";
exit( 1 );
}
name.sin_addr = *( struct in_addr * ) hostinfo->h_addr;
if ( connect( s, ( const sockaddr * ) &name, sizeof( name ) ) < 0 )
{
cerr<<"Could not connect to host"<<"\n";
exit( 1 );
}
else
{
/* if( fcntl( s, F_SETFL, O_NONBLOCK ) == -1 )
{
perror( "fcntl" );
exit( 1 );
} */
char readbuf[1024];
char message[ ] = "START";
rc = send( s, message, strlen(message), 0 );
cout<<"RC on send() was "<<rc<<"\n";
if ( rc > 0 )
{
cout<<"using recv...\n";
while( ( rc = recv( s, readbuf, 1, 0 ) ) > 0 )
{
readbuf[ rc ] = '\0';
cout<<"Server responds with: "<<readbuf<<"\n";
}
return true;
}
else
{
return false;
}
}
}
void
killsignal( int param )
{
fprintf( stderr, "Disconnecting." );
exit( 1 );
}
int
main ( )
{
signal( SIGKILL, killsignal );
signal( SIGINT, killsignal );
char address[] = "localhost";
connectToServer( address );
}
Et le serveur :
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>
#define CLIENT_CONNECTED 0
#define CLIENT_NOT_CONNECTED 1
#define PORT 9999
#define MAX_CLIENTS 100
using namespace std;
struct client {
int socket;
int state;
pthread_t tid;
};
int
sendClient( char *message, int *socket )
{
int rc = 0;
cout<<message<<"\n";
rc = send( *socket, message, strlen(message), 0 );
cout<<"send RC is: "<<rc<<"\n";
}
void
strtochrstr( char **to, string from )
{
int len = from.size( );
*to = ( char * )malloc( ( len + 1 ) * sizeof( char ) );
if ( to == NULL ){
cout<<"out of memory!\n";
exit( 1 );
}
*to[ 0 ] = '\0';
strcpy( *to, from.c_str( ) );
}
int
createSocket ( int *s )
{
struct sockaddr_in name;
if ( ( *s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
{
cerr<<"Server: Socket"<<"\n";
}
name.sin_family = AF_INET;
name.sin_port = htons( (unsigned short int) PORT );
name.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind( *s, ( struct sockaddr * ) &name, sizeof( name ) ) < 0 )
{
cerr<<"Could not bind to socket."<<"\n";
exit( 1 );
}
return *s;
}
void *
serveClient( void *clientState )
{
int c;
int rc = 0;
char readbuf[ 2 ];
char message[ ] = "Message to client";//( char * ) malloc( 300 * sizeof( char ) );
struct client *mystate = ( struct client * ) clientState;
/* Set socket tot NONBLOCKING */
if( fcntl( mystate->socket , F_SETFL, O_NONBLOCK ) == -1 )
{
perror( "fcntl" );
exit( 1 );
}
while ( true )
{
while ( ( rc = recv( mystate->socket, readbuf, 1 , 0 ) ) > 0 )
{
readbuf[ 1 ] = '\0';
cout<<readbuf<<"\n";
}
sendClient( message, &( mystate->socket ) );
}
}
int
listenUp ( int *s )
{
int i = 0;
int error = 0;
pthread_t clientIds[MAX_CLIENTS];
struct client clients[MAX_CLIENTS];
struct sockaddr_in fsaun[MAX_CLIENTS];
int fromlen[MAX_CLIENTS];
while ( i++ < MAX_CLIENTS )
clients[i].state = CLIENT_NOT_CONNECTED;
if ( listen( *s, 10 ) < 0 )
{
cerr<<"Could not listen on socket"<<"\n";
exit( 1 );
}
while ( true )
{
while ( ( clients[i++].state == CLIENT_CONNECTED && i < MAX_CLIENTS ) );
if ( ( clients[i].socket = accept(
*s,
( sockaddr * ) &fsaun[i],
( socklen_t * ) &fromlen[i] ) ) < 0 )
{
cerr<<"Could not accept connection "<<i<<"\n";
}
else
{
error = pthread_create(
&clients[i].tid,
NULL,
serveClient,
(void *)&clients[i]
);
}
i = 0;
}
}
void
killsignal( int param )
{
fprintf( stderr, "Disconnecting.\n" );
}
void
intsignal( int param )
{
fprintf( stderr, "Write error.\n" );
}
int
main ( )
{
signal( SIGKILL, killsignal );
signal( SIGINT, intsignal );
int mySock = createSocket( &mySock );
listenUp( &mySock );
}