source: trunk/user/tcp_client/tcp_client.c @ 678

Last change on this file since 678 was 676, checked in by alain, 4 years ago

Introduce chat application to test the named pipes.

File size: 4.3 KB
RevLine 
[660]1///////////////////////////////////////////////////////////////////////////////////////
2//  file   : tcp_client.c
3//  author : Alain Greiner
4//  date   : march 2020
5///////////////////////////////////////////////////////////////////////////////////////
6//  This file describes a single thread TCP client chat application.
7//  The client send the first message.
8///////////////////////////////////////////////////////////////////////////////////////
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <almosmkh.h>
14#include <unistd.h>
15#include <sys/socket.h>
16
17#define   BUF_SIZE       256
18
19#define   LOCAL_PORT     13
20#define   LOCAL_ADDR     0xAAAAAAAA  // client
21
22#define   REMOTE_PORT    13
23#define   REMOTE_ADDR    0xBBBBBBBB  // server
24
25////////////////////////////
26void client_chat( int fdid )
27{
28    char   buffer[BUF_SIZE];   // string buffer (for send and receive)
29    int    size;               // string length (including NUL)
30    int    nbytes;             // number of characters actually sent or received
31
32    // chat loop
33    while( 1 )
34    {
35        // display client prompt
36        printf("\n[from client] ");
37
38        // build client message
39        size = get_string( buffer , BUF_SIZE );
40
41        // exit chat function when local message is the "exit" string
42        if( strncmp( "exit" , buffer , 4 ) == 0 )
43        {
[676]44            printf("\n[tcp_client stop] local message is <exit> => return to main\n" );
[660]45            return;
46        }
47
48        // send client message
49        nbytes = send( fdid , buffer , size , 0 );
50
51        if( nbytes != size )
52        {
[676]53            printf("\n[tcp_client error] cannot send => return to main\n");
[660]54            return;
55        }
56
57        // display server prompt
58        printf("\n[from server] ");
59
60        // receive server message
[676]61        nbytes = recv( fdid , buffer , BUF_SIZE , 0 );
[660]62
63        if( nbytes < 0 )
64        {
[676]65            printf("\n\n[tcp_client error] cannot receive => return to main\n" );
[660]66            return;
67        }
68        else if( nbytes == 0 )
69        {
[676]70            printf("\n\n[tcp_client stop] receive EOF => return to main\n" );
[660]71            return;
72        }
73       
74        // display server message
75        printf("%s\n", buffer );
76
77    } // end chat loop
78
79}  // end client_chat()
80
81
82////////////////
83int main( void )
84{
85    int                  pid;          // process identifier
86    int                  fdid;         // file index of local socket
87    int                  error;
88
89    struct sockaddr_in   client_sin;   // local client socket
90    struct sockaddr_in   server_sin;   // remote server socket
91
92    unsigned long long   start_cycle;
93
94    // get  start cycle
95    get_cycle( &start_cycle );
[676]96    printf("\n[tcp_client] starts at cycle %d\n", (unsigned int)start_cycle );
[660]97
98    pid = getpid();
99
100    // 1. create TCP socket
101    fdid = socket( AF_INET,
102                   SOCK_STREAM,
103                   0 );
104
105    if( fdid < 0 )
106    {
[676]107        printf("\n[tcp_client error] cannot create socket\n");
[660]108        exit( 0 );
109    }
110    else
111    {
[676]112        printf("\n[tcp_client] created socket[%x,%d]\n", pid, fdid );
[660]113    }
114
115    // 2. bind local socket
116    client_sin.sin_domain = HTONS( AF_INET );
117    client_sin.sin_addr   = HTONL( LOCAL_ADDR );
118    client_sin.sin_port   = HTONS( LOCAL_PORT );
119
120    error = bind( fdid,
121                  (sockaddr_t *)(&client_sin),
122                  sizeof(sockaddr_t) );
123    if( error )
124    {
[676]125        printf("\n[tcp_client error] bind failure on socketi[%x,%d]\n", pid, fdid );
[660]126        exit( 0 );
127    }
128
[676]129    printf("\n[tcp_client] socket[%x,%d] bound : [%x,%x]\n",
[660]130    pid, fdid, client_sin.sin_addr, (unsigned int)client_sin.sin_port );
131
132    // 3. connect to remote socket
133    server_sin.sin_domain = HTONS( AF_INET );
134    server_sin.sin_addr   = HTONL( REMOTE_ADDR );
135    server_sin.sin_port   = HTONS( REMOTE_PORT );
136
137    error = connect( fdid,
138                     (sockaddr_t *)(&server_sin),
139                     sizeof(sockaddr_t) );
140    if( error )
141    {
[676]142        printf("\n[tcp_client error] connect failure on socket[%x,%d]\n", pid, fdid );
[660]143        exit( 0 );
144    }
145
[676]146    printf("\n[tcp_client] socket[%x,%d] connected to server [%x,%x]\n",
[660]147    pid, fdid, server_sin.sin_addr, server_sin.sin_port );
148
149    // 4. call chat function
150    client_chat( fdid );
151
152    // 5. close local socket
153    close( fdid );
154
[676]155    printf("\n[tcp_client] closed socket[%x,%d]\n", pid, fdid );
[660]156
157    exit(0);
158
159    return 0;
160}
Note: See TracBrowser for help on using the repository browser.