source: trunk/instant_messenger/socket/BKP_20071105/BKP_20071026/BKP_20071019/BKP_20071018/BKP_20071009/BKP_20071008/BKP/server.c @ 151

Revision 151, 7.0 KB checked in by niltonneto, 16 years ago (diff)

Commit da nova versão do módulo, usando agente em C.
Vide Página do módulo do Trac:
http://www.expressolivre.org/dev/wiki/messenger

A versão anterior encontra-se na subpasta bkp (32/64).

Line 
1#include "server.h"
2
3void my_shutdown(int n){
4        printf("server recvd SIGPIPE");
5        exit(1);
6}
7
8int main(int argc, char ** argv)
9{
10        /* variables to parse arguments */
11        extern int optind,
12                           optopt;
13        extern char * optarg;
14
15        char * log_file;
16        int c           = (int)NULL,
17                errflg  = (int)NULL,
18                verbose = (int)NULL,
19                optval  = 1;
20
21        socklen_t optlen = sizeof(optval);
22
23        /* fd -> file descriptor */
24        int socket_server_fd    = (int)NULL,
25                socket_server_port      = (int)NULL,
26                socket_accept_fd        = (int)NULL,
27                sockaddr_in_size        = sizeof(struct sockaddr_in),
28                err                                     = (int)NULL;
29
30        /* Internet socket address stuct */
31        struct sockaddr_in server_addr,
32                                           accept_addr;
33
34        struct client * clients = (struct client *) NULL,
35                                  * current = (struct client *) NULL;
36
37        pthread_t threads;
38
39        /* clear screen */
40        system(__CLEAR_SCREEN__);
41        signal(SIGPIPE, my_shutdown);
42
43        while ( (c = getopt(argc, argv, ":vp:")) != -1 )
44        {
45                switch ( c )
46                {
47                        case 'p':
48                                if ( socket_server_port = strtol(optarg, 0, 10) == 0 )
49                                {
50                                        fprintf(stderr, "Option -%c requires a valid port and '%s' isn't valid\n", optopt, optarg);
51                                        ++errflg;
52                                }
53                                break;
54                        case 'v':
55                                verbose = 1;
56                                break;
57                        case ':':
58                                /* -f or -o without operand */
59                                fprintf(stderr, "Option -%c requires an operand\n", optopt);
60                                ++errflg;
61                                break;
62                        case '?':
63                                fprintf(stderr, "Unrecognized option: -%c\n", optopt);
64                                ++errflg;
65                }
66        }
67        if ( errflg )
68        {
69                fprintf(stderr, "usage: . . . \n\n");
70                exit(2);
71        }
72        //exit(0);
73
74        /*if ( argc != 2 || (socket_server_port = strtol(argv[1], 0, 10)) == 0 )
75                usage();*/
76
77        /* make a socket */
78        socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
79        if ( socket_server_fd == __SOCKET_ERROR__ )
80        {
81                printf("\nCould not make a socket\n");
82                return 0;
83        }
84
85        bzero((char *) &server_addr, sockaddr_in_size);
86        bzero((char *) &accept_addr, sockaddr_in_size);
87
88        if ( !socket_server_port )
89                socket_server_port = __DEFAULT_OPEN_PORT__;
90
91        /* fill address struct */
92        server_addr.sin_addr.s_addr     = INADDR_ANY;
93        server_addr.sin_port            = htons(socket_server_port);
94        server_addr.sin_family          = AF_INET;
95        bzero(&(server_addr.sin_zero), 8);
96
97        if ( __DEBUG__  || verbose )
98                printf("\nBinding to port %d...\n", socket_server_port);
99
100        /* bind to a port */
101        if ( bind(socket_server_fd, (struct sockaddr *)&(server_addr), sizeof(server_addr)) == __SOCKET_ERROR__ )
102        {
103                printf("\nCould not connect to host\n");
104                exit(1);
105        }
106
107        /* get port number */
108        getsockname(socket_server_fd, (struct sockaddr *)&(server_addr), (socklen_t *) &(sockaddr_in_size));
109        if ( __DEBUG__  || verbose )
110        {
111                printf("\nopened socket as fd (%d) on port (%d) for stream i/o\n", socket_server_fd, ntohs(server_addr.sin_port));
112
113                printf("Server\n\
114                                sin_family        = %d\n\
115                                sin_addr.s_addr   = %d\n\
116                                sin_port          = %d\n"
117                                , server_addr.sin_family
118                                , server_addr.sin_addr.s_addr
119                                , ntohs(server_addr.sin_port)
120                          );
121                printf("\nMaking a listen queue of %d elements", __QUEUE_SIZE__);
122        }
123
124        /* establish listen queue */
125        if ( listen(socket_server_fd, __QUEUE_SIZE__) == __SOCKET_ERROR__ )
126        {
127                printf("\nCould not listen\n");
128                return 0;
129        }
130
131        for ( ; ; )
132        {
133                if ( __DEBUG__  || verbose )
134                        puts("\nWaiting for a connection\n");
135
136                /* get the connected socket */
137                socket_accept_fd = accept(socket_server_fd, (struct sockaddr *) &(accept_addr), (socklen_t *) &(sockaddr_in_size));
138                fcntl(socket_accept_fd, F_SETFL, fcntl(socket_accept_fd, F_GETFL, 0) | O_NDELAY);
139
140                if ( setsockopt(socket_accept_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0)
141                {
142                        perror("setsockopt()");
143                        exit(EXIT_FAILURE);
144                }
145
146                int val;
147                val = 10; /* 10 sec before starting probes */
148                setsockopt (socket_accept_fd, SOL_TCP, TCP_KEEPIDLE, &val, sizeof (val));
149                val = 2; /* 2 probes max */
150                setsockopt (socket_accept_fd, SOL_TCP, TCP_KEEPCNT, &val, sizeof (val));
151                val = 5; /* 5 seconds between each probe */
152                setsockopt (socket_accept_fd, SOL_TCP, TCP_KEEPINTVL, &val, sizeof (val));
153
154
155                if ( socket_accept_fd > -1 )
156                {
157                        if ( clients == (struct client *) NULL )
158                                current = clients;
159                        else
160                                while ( (current = clients->next) != (struct client *) NULL );
161
162                        current                         = (struct client *) malloc(sizeof(struct client));
163                        current->next           = (struct client *) NULL;
164                        current->fd                     = socket_accept_fd;
165                        current->sockaddr       = accept_addr;
166                        current->last           = time(NULL);
167
168                        pthread_create(&(threads), NULL, handler, (void *) current);
169                }
170                puts("jah era #5");
171        }
172        pthread_exit(NULL);
173}
174
175void * handler(void * pClient)
176{
177    char buffer_client[__BUFFER_SIZE__],
178                 buffer_jabber[__BUFFER_SIZE__];
179    struct client * client = (struct client *) pClient;
180    int i = 0, err;
181        time_t last;
182
183        char ip[46];
184        unsigned short port;
185        inet_ntop(AF_INET, &(client->sockaddr.sin_addr), ip, sizeof (ip));
186        port = ntohs(client->sockaddr.sin_port);
187        printf("\nGot a connection from %s, port %hu\n", ip, port);
188        //fcntl( client->fd, F_SETFL, fcntl( client->fd, F_GETFL ) & ~O_NONBLOCK );
189        //printf(":::client %d\n\n\n", fcntl( client->fd, F_GETFL, 0));
190        //printf(":::client %d\n\n\n", fcntl( client->fd, F_SETFL, fcntl( client->fd, F_GETFL ) & ~O_NONBLOCK ));
191        /*---------------------------------------------------*/
192
193        int jabber_fd           = (int)NULL,
194                jabber_port             = (int)NULL,
195                jabber_error    = (int)NULL;
196
197        struct sockaddr_in jabber_addr;
198
199        jabber_port = __DEFAULT_JABBER_PORT__;
200        //jabber_port = strtol(__DEFAULT_JABBER_PORT__, 0, 10);
201        jabber_fd = socket(AF_INET, SOCK_STREAM, 0);
202        fcntl(jabber_fd, F_SETFL, fcntl(jabber_fd, F_GETFL, 0) | O_NDELAY);
203
204        jabber_addr.sin_family = AF_INET;
205        inet_aton(__DEFAULT_JABBER_IP__, &jabber_addr.sin_addr);
206        jabber_addr.sin_port = htons(jabber_port);
207
208        jabber_error = connect(jabber_fd, (struct sockaddr *) &(jabber_addr), sizeof(jabber_addr));
209
210        last = time(NULL);
211        int client_is_connected = -1;
212        int jabber_is_connected = -1;
213        int sockaddr_in_size    = sizeof(struct sockaddr_in);
214        while ( client_is_connected != 0 )
215        {
216                puts("begin loop");
217                /* read from client */
218                puts("\tread - client");
219                bzero(buffer_client, __BUFFER_SIZE__);
220                if ( (client_is_connected = read(client->fd, buffer_client, __BUFFER_SIZE__)) != 0 && strlen(buffer_jabber) > 0 )
221                {
222                        puts("\twrite - jabber");
223                        /* write in the client */
224                        write(client->fd, buffer_jabber, strlen(buffer_jabber));
225                }
226
227                /*if ( client_is_connected == 0 )
228                        break;*/
229
230                /* read from jabber service */
231                puts("\tread - jabber");
232                bzero(buffer_jabber, __BUFFER_SIZE__);
233                if ( (jabber_is_connected = read(jabber_fd, buffer_jabber, __BUFFER_SIZE__)) && strlen(buffer_client) > 0 )
234                {
235                        puts("\twrite - client");
236                        /* write in the jabber service */
237                        write(jabber_fd, buffer_client, strlen(buffer_client));
238                }
239
240                if ( jabber_is_connected == 0 )
241                        client_is_connected = jabber_is_connected;
242
243                puts("end loop");
244                usleep(500000);
245        }
246
247    if ( close(jabber_fd) == __SOCKET_ERROR__ )
248    {
249        printf("\nCould not close jabber socket\n");
250        return 0;
251    }
252        /*---------------------------------------------------*/
253    if ( close(client->fd) == __SOCKET_ERROR__ )
254    {
255        printf("\nCould not close socket\n");
256        return 0;
257    }
258
259    fflush(stdin);
260    fflush(stdout);
261        free(client);
262    pthread_exit(NULL);
263}
Note: See TracBrowser for help on using the repository browser.