/////////////////////////////////////////////////////////////////////////////////////// // file : tcp_client.c // author : Alain Greiner // date : march 2020 /////////////////////////////////////////////////////////////////////////////////////// // This file describes a single thread TCP client chat application. // The client send the first message. /////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #define BUF_SIZE 256 #define LOCAL_PORT 13 #define LOCAL_ADDR 0xAAAAAAAA // client #define REMOTE_PORT 13 #define REMOTE_ADDR 0xBBBBBBBB // server //////////////////////////// void client_chat( int fdid ) { char buffer[BUF_SIZE]; // string buffer (for send and receive) int size; // string length (including NUL) int nbytes; // number of characters actually sent or received // chat loop while( 1 ) { // display client prompt printf("\n[from client] "); // build client message size = get_string( buffer , BUF_SIZE ); // exit chat function when local message is the "exit" string if( strncmp( "exit" , buffer , 4 ) == 0 ) { printf("\n[tcp_client stop] local message is => return to main\n" ); return; } // send client message nbytes = send( fdid , buffer , size , 0 ); if( nbytes != size ) { printf("\n[tcp_client error] cannot send => return to main\n"); return; } // display server prompt printf("\n[from server] "); // receive server message nbytes = recv( fdid , buffer , BUF_SIZE , 0 ); if( nbytes < 0 ) { printf("\n\n[tcp_client error] cannot receive => return to main\n" ); return; } else if( nbytes == 0 ) { printf("\n\n[tcp_client stop] receive EOF => return to main\n" ); return; } // display server message printf("%s\n", buffer ); } // end chat loop } // end client_chat() //////////////// int main( void ) { int pid; // process identifier int fdid; // file index of local socket int error; struct sockaddr_in client_sin; // local client socket struct sockaddr_in server_sin; // remote server socket unsigned long long start_cycle; // get start cycle get_cycle( &start_cycle ); printf("\n[tcp_client] starts at cycle %d\n", (unsigned int)start_cycle ); pid = getpid(); // 1. create TCP socket fdid = socket( AF_INET, SOCK_STREAM, 0 ); if( fdid < 0 ) { printf("\n[tcp_client error] cannot create socket\n"); exit( 0 ); } else { printf("\n[tcp_client] created socket[%x,%d]\n", pid, fdid ); } // 2. bind local socket client_sin.sin_domain = HTONS( AF_INET ); client_sin.sin_addr = HTONL( LOCAL_ADDR ); client_sin.sin_port = HTONS( LOCAL_PORT ); error = bind( fdid, (sockaddr_t *)(&client_sin), sizeof(sockaddr_t) ); if( error ) { printf("\n[tcp_client error] bind failure on socketi[%x,%d]\n", pid, fdid ); exit( 0 ); } printf("\n[tcp_client] socket[%x,%d] bound : [%x,%x]\n", pid, fdid, client_sin.sin_addr, (unsigned int)client_sin.sin_port ); // 3. connect to remote socket server_sin.sin_domain = HTONS( AF_INET ); server_sin.sin_addr = HTONL( REMOTE_ADDR ); server_sin.sin_port = HTONS( REMOTE_PORT ); error = connect( fdid, (sockaddr_t *)(&server_sin), sizeof(sockaddr_t) ); if( error ) { printf("\n[tcp_client error] connect failure on socket[%x,%d]\n", pid, fdid ); exit( 0 ); } printf("\n[tcp_client] socket[%x,%d] connected to server [%x,%x]\n", pid, fdid, server_sin.sin_addr, server_sin.sin_port ); // 4. call chat function client_chat( fdid ); // 5. close local socket close( fdid ); printf("\n[tcp_client] closed socket[%x,%d]\n", pid, fdid ); exit(0); return 0; }