source: trunk/user/udp_chat/udp_chat.c @ 690

Last change on this file since 690 was 682, checked in by alain, 3 years ago

Introduce three new applications:

  • windows : to test the FBF windows kernel manager
  • udp_chat : chat application based on UDP sockets.
  • tcp_chat : chat application based on TCP sockets (including packet loss recovery).
File size: 6.9 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////////
2//  file   : udp_chat.c
3//  author : Alain Greiner
4//  date   : march 2020
5///////////////////////////////////////////////////////////////////////////////////////
6//  This file describes an UDP based chat application.
7//  It can be used to launch the UDP client, or the UDP server application.
8//  The client send the first message. The server wait this first message.
9//  The 4 command line arguments are: is_server, local_ip_addr, remote_ip_addr, port
10///////////////////////////////////////////////////////////////////////////////////////
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <almosmkh.h>
16#include <unistd.h>
17#include <sys/socket.h>
18
19#define   BUF_SIZE       256
20
21////////////////////////////
22void client_chat( int fdid )
23{
24    char   buffer[BUF_SIZE];   // string buffer (for both send and receive)
25    int    size;               // string length (including NUL)
26    int    nbytes;             // number of characters actually sent or received
27
28    while( 1 )
29    {
30        //////// display client prompt to wait local client message ////////
31        printf("\n[local client] ");
32
33        // build local client message
34        size = get_string( buffer , BUF_SIZE );
35
36        // exit chat function when client message is the "exit" string
37        if( strncmp( "exit" , buffer , 4 ) == 0 )
38        {
39            printf("\n[client_chat] local message is <exit> => return to main\n" );
40            return;
41        }
42 
43       // send local client message
44        nbytes = send( fdid , buffer, size, 0 );      // flags
45
46        if( nbytes != size )
47        {
48            printf("\n[client_chat error] cannot send => return to main\n");
49            return;
50        }
51
52        ///////// display server prompt to wait remote server message ///////
53        printf("\n[remote server] ");
54
55        // receive remote server message
56        nbytes = recv( fdid , buffer , BUF_SIZE , 0 ); 
57
58        if( nbytes < 0 )
59        {
60            printf("\n\n[client_chat error] cannot receive => return to main\n" );
61            return;
62        }
63        else if( nbytes == 0 )
64        {
65            printf("\n\n[client_chat] receive EOF => return to main\n" );
66            return;
67        }
68       
69        // display remote server message
70        printf("%s\n", buffer );
71    } 
72}  // end client_chat()
73
74
75////////////////////////////
76void server_chat( int fdid )
77{
78    char   buffer[BUF_SIZE];   // string buffer (for send and receive)
79    int    size;               // string length (including NUL)
80    int    nbytes;             // number of characters actually sent or received
81
82    while( 1 )
83    {
84        //////// display client prompt to wait remote client message ///////
85        printf("\n[remote client] ");
86
87        // receive remote client message
88        nbytes = recv( fdid , buffer , BUF_SIZE , 0 ); 
89
90        if( nbytes < 0 )
91        {
92            printf("\n\n[server_chat error] cannot receive => return to main\n" );
93            return;
94        }
95        else if( nbytes == 0 )
96        {
97            printf("\n\n[server_chat] receive EOF => return to main\n" );
98            return;
99        }
100       
101        // display remote client message
102        printf("%s\n", buffer );
103
104        //////// display server prompt to wait local server message //////
105        printf("\n[local server] ");
106
107        // build local server message
108        size = get_string( buffer , BUF_SIZE );
109
110        // exit chat function when server message is the "exit" string
111        if( strncmp( "exit" , buffer , 4 ) == 0 )
112        {
113            printf("\n[server_chat] local message is <exit> => return to main\n" );
114            return;
115        }
116
117        // send local server message
118        nbytes = send( fdid , buffer , size , 0 );
119
120        if( nbytes != size )
121        {
122            printf("\n[server_chat error] cannot send => return to main\n");
123            return;
124        }
125    } 
126}  // end server_chat()
127
128
129///////////////////////
130int main( int     argc,
131          char ** argv )
132{
133    int                  pid;          // process identifier
134    int                  fdid;         // file index of local socket
135    int                  error;
136
137    sockaddr_in_t        local_sin;   // local socket internet address
138    sockaddr_in_t        remote_sin;  // remote socket internet address
139
140    unsigned long long   start_cycle;
141
142    int                  addr_length = sizeof(sockaddr_t);
143
144    // get  start cycle
145    get_cycle( &start_cycle );
146
147    // get PID
148    pid = getpid();
149
150    // get arguments
151    if( argc != 4 )
152    {
153        printf("\n  usage : udp_chat is_server local_addr remote_addr port\n");
154        exit( 0 );
155    }
156
157    int  is_server    = atoi( argv[0] );
158    int  local_addr   = atoi( argv[1] );
159    int  remote_addr  = atoi( argv[2] );
160    int  port         = atoi( argv[3] );
161
162    if( is_server )
163    printf("\n[udp_chat] SERVER / pid %x / cycle %d"
164    "  local_addr %x  / remote_addr %x / port %x\n",
165    pid, (unsigned int)start_cycle, local_addr,  remote_addr, port );
166    else           
167    printf("\n[udp_chat] CLIENT / pid %x / cycle %d"
168    "  local_addr %x  / remote_addr %x / port %x\n",
169    pid, (unsigned int)start_cycle, local_addr,  remote_addr, port );
170
171    // initialize local_sin
172    local_sin.sin_domain = HTONS( AF_INET );
173    local_sin.sin_addr   = HTONL( local_addr );
174    local_sin.sin_port   = HTONS( port );
175
176    // initialize remote_sin
177    remote_sin.sin_domain = HTONS( AF_INET );
178    remote_sin.sin_addr   = HTONL( remote_addr );
179    remote_sin.sin_port   = HTONS( port );
180
181    // 1. create local UDP socket
182    fdid = socket( AF_INET,
183                   SOCK_DGRAM,
184                   0 );
185
186    if( fdid < 0 )
187    {
188        printf("\n[udp_chat error] cannot create socket\n");
189        exit( 0 );
190    }
191    else
192    {
193        printf("\n[udp_chat] created socket[%x,%d]\n", pid, fdid );
194    }
195
196    // 2. bind local socket
197    error = bind( fdid,
198                  (sockaddr_t *)(&local_sin),
199                  sizeof(sockaddr_t) );
200    if( error )
201    {
202        printf("\n[udp_chat error] bind failure on socketi[%x,%d]\n", pid, fdid );
203        exit( 0 );
204    }
205    else
206    {
207        printf("\n[udp_chat] socket[%x,%d] bound : [%x,%x]\n",
208        pid, fdid, local_sin.sin_addr, (unsigned int)local_sin.sin_port );
209    }
210
211
212    // 3. connect local socket to remote socket
213    error = connect( fdid,
214                     (sockaddr_t *)(&remote_sin),
215                     addr_length );
216    if( error )
217    {
218        printf("\n[server_chat error] cannot connect to remote => return to main\n" );
219        exit( 0 );
220    }
221    else
222    {
223        printf("\n[server_chat] successfully connected to remote client\n");
224    }
225
226    // 4. call chat function
227    if( is_server ) server_chat( fdid );
228    else            client_chat( fdid );
229
230    // 5. close local socket
231    close( fdid );
232
233    printf("\n[udp_chat] closed socket[%x,%d]\n", pid, fdid );
234
235    exit(0);
236
237    return 0;
238}
Note: See TracBrowser for help on using the repository browser.