/* * sss_handle_accept() * * This routine is called when ever our listening socket has an incoming * connection request. Since this example has only data transfer socket, * we just look at it to see whether its in use... if so, we accept the * connection request and call the telent_send_menu() routine to transmit * instructions to the user. Otherwise, the connection is already in use; * reject the incoming request by immediately closing the new socket. * * We'll also print out the client's IP address. */ void sss_handle_accept(int listen_socket, SSSConn* conn) { int socket, len; struct sockaddr_in incoming_addr; len = sizeof(incoming_addr); if ((conn)->fd == -1) { if((socket=accept(listen_socket,(struct sockaddr*)&incoming_addr,&len))<0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE, "[sss_handle_accept] accept failed"); } else { (conn)->fd = socket; sss_send_menu(conn); printf("[sss_handle_accept] accepted connection request from %s\n", inet_ntoa(incoming_addr.sin_addr)); } } else { printf("[sss_handle_accept] rejected connection request from %s\n", inet_ntoa(incoming_addr.sin_addr)); } return; }
/* * SSSSimpleSocketServerTask() * * This MicroC/OS-II thread spins forever after first establishing a listening * socket for our sss connection, binding it, and listening. Once setup, * it perpetually waits for incoming data to either the listening socket, or * (if a connection is active), the sss data socket. When data arrives, * the approrpriate routine is called to either accept/reject a connection * request, or process incoming data. */ void SSSSimpleSocketServerTask() { // Объявления используемых переменных int errcode; int is_alive; int flag_exit = 0; char buffer_in[1024]; char buffer_out[3] = {'1','\r','\n'}; int len_buff = 1024; int fd_listen; struct sockaddr_in addr; edge_capture = 0xF; // Регистрируем обработчик прерываний от кнопок init_button_pio(); while (1) { // Создаем сокет, если не удалось создать, выдаем сообщение в консоль if ((fd_listen = socket(AF_INET, SOCK_STREAM, 0)) < 0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[sss_task] Socket creation failed"); } // Инициализируем структуру sockaddr_in, указав семейство адресов, // IP-адрес и номер порта серверного приложения // (для примера см. simple_socket_server) addr.sin_family = AF_INET; addr.sin_port = htons(SSS_PORT); addr.sin_addr.s_addr = inet_addr("192.168.21.171"); // Устанавливаем соединение с сервером errcode = connect(fd_listen, (struct sockaddr *)&addr, sizeof(addr)); if (errcode) { printf("Unable to connect to server!\n"); return; } // Получаем меню от сервера, выводим в консоль errcode = recv(fd_listen, &buffer_in, len_buff, 0); if (errcode == SOCKET_ERROR) { printf("Unable to get data from server!\n"); return; } printf(buffer_in); is_alive = 1; do { // Ожидаем сообщение о нажатии кнопки от обработчика прерывания if (edge_capture != NONE_PRESSED) // if button pressed { switch(edge_capture) { case (BTN_RIGHT_PRESSED): buffer_out[0] = 'q'; flag_exit = 1; break; case (BTN_LEFT_PRESSED): buffer_out[0] = '1'; break; case (BTN_CNTR_LEFT): buffer_out[0] = '2'; break; case (BTN_CNTR_RIGHT): buffer_out[0] = '3'; break; } // Отправляем соответствующую команду на сервер errcode = send(fd_listen, &buffer_out, 3, 0); if (errcode == SOCKET_ERROR) { printf("Unable to send data to server!\n"); return; } edge_capture = 0xF; // Если была отправлена команда 'q', выходим из внутреннего // цикла if (flag_exit) { flag_exit = 0; break; } // В противном случае получаем ответ от сервера, выводим его // в консоль errcode = recv(fd_listen, &buffer_in, len_buff, 0); if (errcode == SOCKET_ERROR) { printf("Unable to get data from server!\n"); return; } printf(buffer_in); } } while (is_alive); // Разрываем соединение errcode = socketclose(fd_listen); if (errcode == SOCKET_ERROR) { printf("Unable to close connection!\n"); return; } printf("Connection closed.\n"); // Ожидаем сообщение о нажатии кнопки от обработчика прерывания // Перед повторным установлением соединения while (edge_capture == NONE_PRESSED); } /* while (1) */ }
/* * SSSSimpleSocketServerTask() * * This MicroC/OS-II thread spins forever after first establishing a listening * socket for our sss connection, binding it, and listening. Once setup, * it perpetually waits for incoming data to either the listening socket, or * (if a connection is active), the sss data socket. When data arrives, * the approrpriate routine is called to either accept/reject a connection * request, or process incoming data. */ void SSSSimpleSocketServerTask() { int fd_listen, max_socket; struct sockaddr_in addr; static SSSConn conn; fd_set readfds; /* * Sockets primer... * The socket() call creates an endpoint for TCP of UDP communication. It * returns a descriptor (similar to a file descriptor) that we call fd_listen, * or, "the socket we're listening on for connection requests" in our sss * server example. */ if ((fd_listen = socket(AF_INET, SOCK_STREAM, 0)) < 0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[sss_task] Socket creation failed"); } /* * Sockets primer, continued... * Calling bind() associates a socket created with socket() to a particular IP * port and incoming address. In this case we're binding to SSS_PORT and to * INADDR_ANY address (allowing anyone to connect to us. Bind may fail for * various reasons, but the most common is that some other socket is bound to * the port we're requesting. */ addr.sin_family = AF_INET; addr.sin_port = htons(SSS_PORT); addr.sin_addr.s_addr = INADDR_ANY; if ((bind(fd_listen,(struct sockaddr *)&addr,sizeof(addr))) < 0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[sss_task] Bind failed"); } /* * Sockets primer, continued... * The listen socket is a socket which is waiting for incoming connections. * This call to listen will block (i.e. not return) until someone tries to * connect to this port. */ if ((listen(fd_listen,1)) < 0) { alt_NetworkErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[sss_task] Listen failed"); } /* At this point we have successfully created a socket which is listening * on SSS_PORT for connection requests from any remote address. */ sss_reset_connection(&conn); printf("[sss_task] Simple Socket Server listening on port %d\n", SSS_PORT); while(1) { /* * For those not familiar with sockets programming... * The select() call below basically tells the TCPIP stack to return * from this call when any of the events I have expressed an interest * in happen (it blocks until our call to select() is satisfied). * * In the call below we're only interested in either someone trying to * connect to us, or data being available to read on a socket, both of * these are a read event as far as select is called. * * The sockets we're interested in are passed in in the readfds * parameter, the format of the readfds is implementation dependant * Hence there are standard MACROs for setting/reading the values: * * FD_ZERO - Zero's out the sockets we're interested in * FD_SET - Adds a socket to those we're interested in * FD_ISSET - Tests whether the chosen socket is set */ FD_ZERO(&readfds); FD_SET(fd_listen, &readfds); max_socket = fd_listen+1; if (conn.fd != -1) { FD_SET(conn.fd, &readfds); if (max_socket <= conn.fd) { max_socket = conn.fd+1; } } select(max_socket, &readfds, NULL, NULL, NULL); /* * If fd_listen (the listening socket we originally created in this thread * is "set" in readfs, then we have an incoming connection request. We'll * call a routine to explicitly accept or deny the incoming connection * request (in this example, we accept a single connection and reject any * others that come in while the connection is open). */ if (FD_ISSET(fd_listen, &readfds)) { sss_handle_accept(fd_listen, &conn); } /* * If sss_handle_accept() accepts the connection, it creates *another* * socket for sending/receiving data over sss. Note that this socket is * independant of the listening socket we created above. This socket's * descriptor is stored in conn.fd. If conn.fs is set in readfs... we have * incoming data for our sss server, and we call our receiver routine * to process it. */ else { if ((conn.fd != -1) && FD_ISSET(conn.fd, &readfds)) { sss_handle_receive(&conn); } } } /* while(1) */ }