source: trunk/user/tcp_server/tcp_server.c @ 674

Last change on this file since 674 was 668, checked in by alain, 4 years ago

typos...

File size: 4.6 KB
RevLine 
[660]1///////////////////////////////////////////////////////////////////////////////////////
2//  file   : tcp_server.c
3//  author : Alain Greiner
4//  date   : march 2020
5///////////////////////////////////////////////////////////////////////////////////////
6//  This file describes a single thread TCP server 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   MAX_PENDING_CONNECT  16
20
21#define   LOCAL_PORT           13
22#define   LOCAL_ADDR           0xBBBBBBBB
23
24////////////////////////////
25void server_chat( int fdid )
26{
27    char   buffer[BUF_SIZE];   // string buffer (for send and receive)
28    int    size;               // string length (including NUL)
29    int    nbytes;             // number of characters actually sent or received
30
31    // chat loop
32    while( 1 )
33    {
34        // display client prompt
35        printf("\n[from client] ");
36
37        // get client message
38        nbytes = recv( fdid, buffer, BUF_SIZE, 0 );
39
40        if( nbytes < 0 )
41        {
42            printf("\n\n[server] receive error => return to main\n" );
43            return;
44        }
45        else if( nbytes == 0 )
46        {
47            printf("\n\n[server] receive EOF => return to main\n" );
48            return;
49        }
50
51        // display client message
52        printf("%s\n", buffer );
53
54        // display server prompt
55        printf("\n[from server] ");
56
57        // build server message
58        size = get_string( buffer , BUF_SIZE );
59
60        // exit chat function when local message is the "exit" string
61        if( strncmp( "exit" , buffer , 4 ) == 0 )
62        {
63            return;
64        }
65
66        // send server message
67        nbytes = send( fdid , buffer , size , 0 ) ;
68
69        if( nbytes != size )
70        {
71            printf("\n[server] send error => chat return to main\n" );
72            return;
73        }
74    }  // end chat loop
75
76}  // end server_chat()
77
78
79////////////////
80int main( void )
81{
82    int                  pid;          // process pid
83    int                  listen_fdid;  // listen socket identifier
84    int                  chat_fdid;    // chat socket identifier
85    int                  error;
86
87    struct sockaddr_in   server_sin;   // server socket IP address
88    struct sockaddr_in   client_sin;   // client socket IP address
89
90    unsigned long long   start_cycle;
91
92    int                  addr_length = sizeof(sockaddr_t);
93
94    // get  start cycle
95    get_cycle( &start_cycle );
96
97    pid = getpid();
98
99    printf("\n[server] starts at cycle %d\n",
100    (unsigned int)start_cycle );
101
102    // 1. create TCP socket
103    listen_fdid = socket( AF_INET,
104                        SOCK_STREAM,
105                        0 );
106
107    if( listen_fdid < 0 )
108    {
109        printf("\n[server error] cannot create socket\n");
110        exit( 0 );
111    }
112    else
113    {
114        printf("\n[server] created socket[%x,%d]\n", pid, listen_fdid );
115    }
116
117    // 2. bind local socket
118    server_sin.sin_domain = HTONS( AF_INET );
119    server_sin.sin_addr   = HTONL( LOCAL_ADDR );
120    server_sin.sin_port   = HTONS( LOCAL_PORT );
121
122    error = bind( listen_fdid,
123                  (sockaddr_t *)(&server_sin),
124                  sizeof(sockaddr_t) );
125    if( error )
126    {
127        printf("\n[server error] bind failure for socket[%x,%d]\n",
128        pid, listen_fdid );
129        exit( 0 );
130    }
131
[668]132    printf("\n[server] listening socket[%x,%d] bound : [%x,%x]\n",
133    pid, listen_fdid, server_sin.sin_addr, server_sin.sin_port );
134
[660]135    // 3. Listen clients connection requests
136    error = listen( listen_fdid , MAX_PENDING_CONNECT );
137                     
138    if( error )
139    {
140        printf("\n[server error] listen failure for socket[%x,%d]\n",
141        pid, listen_fdid );
142        exit( 0 );
143    }
144
[668]145    printf("\n[server] listening socket[%x,%d] waiting connection request\n",
146    pid, listen_fdid );
[660]147   
148    // 4. accept connection(s)
149    chat_fdid = accept( listen_fdid,
150                        (sockaddr_t *)&client_sin,
151                        &addr_length );
152
[668]153    if( chat_fdid < 0 )
[660]154    {
155        printf("\n[server error] accept failure on socket[%x,%d]\n",
156        pid, listen_fdid );
157        exit( 0 );
158    }
159
[668]160    printf("\n[server] chat socket[%x,%d] accepted client [%x,%x]\n",
161    pid, chat_fdid , client_sin.sin_addr , client_sin.sin_port );
162
[660]163    // 5. call chat function
[668]164    server_chat( chat_fdid ); 
[660]165
166    // 6. close listen and chat sockets
167    close( chat_fdid );
168    close( listen_fdid );
169
170    printf("\n[server] closed both <listen> & <chat> sockets\n" );
171
172    exit(0);
173
174    return 0;
175}
Note: See TracBrowser for help on using the repository browser.