/*Setup Server Socket Function Variable Definition: -- service: socket service name or port number Return value: server socket number */ int setupServerSocket(const char *service){ struct addrinfo address_criteria; //criteria for address match struct addrinfo *server_address; //list of server addresses struct addrinfo *address; //pointer to addresses node struct sockaddr_storage local_address; //print local address socklen_t address_size; //address size int server_socket = -1; //socket descriptor for server int return_value; //return value //Construct the server address structure memset(&address_criteria, 0, sizeof(address_criteria)); //zero the address_criteria address_criteria.ai_family = AF_UNSPEC; //any address family address_criteria.ai_flags = AI_PASSIVE; //accept on any address/port address_criteria.ai_socktype = SOCK_STREAM; //only stream sockets address_criteria.ai_protocol = IPPROTO_TCP; //only tcp protocol //Get address/name information return_value = getaddrinfo(NULL, service, &address_criteria, &server_address); //Success returns zero if (return_value != 0){ dieWithUserMessage("getaddrinfo() failed!", gai_strerror(return_value)); } //Create socket for incoming connections for (address = server_address; address != NULL; address = address->ai_next){ //Initialize the server socket server_socket = -1; //Create socket for incoming connections server_socket = socket(server_address->ai_family, server_address->ai_socktype, server_address->ai_protocol); //if socket creation failed, try next address in the list if (server_socket < 0){ continue; } //Bind to the server local address and set socket to the list if ((bind(server_socket, server_address->ai_addr, server_address->ai_addrlen) == 0) && (listen(server_socket, MAX_PENDING) == 0)){ //Get address size address_size = sizeof(local_address); //Get socket name if (getsockname(server_socket, (struct sockaddr*)&local_address, &address_size) < 0){ dieWithSystemMessage("getsockname() failed!"); } //Output local address and port of socket(listening address and port) fputs("Binding to ", stdout); printSocketAddress((struct sockaddr*)&local_address, stdout); fputc('\n', stdout); //Bind and list successful break; } //Close and try again close(server_socket); } //Free address list allocated by getaddrinfo() freeaddrinfo(server_address); return server_socket; }
int setupTCPServerSocket(const char* service) { // Construct the server address structure struct addrinfo addrCriteria; // Criteria for address match struct addrinfo* servAddr; // List of server addresses int servSock; int rtnVal; memset(&addrCriteria, 0, sizeof(addrCriteria)); // Zero out structure addrCriteria.ai_family = AF_INET; // IPv4 ONLY addrCriteria.ai_flags = AI_PASSIVE; // Accept on any address/port addrCriteria.ai_socktype = SOCK_STREAM; // Only stream sockets addrCriteria.ai_protocol = IPPROTO_TCP; // Only TCP protocol rtnVal = getaddrinfo(0, service, &addrCriteria, &servAddr); if (rtnVal != 0) DieWithMessage("getaddrinfo() failed", gai_strerror(rtnVal)); servSock = -1; // Iterate through possible server addresses and choose one that works // (usually IPv4 is the first choice) struct addrinfo* addr; int i=0; for (addr = servAddr; addr != 0; addr = addr->ai_next) i++; #ifndef NDEBUG printf("%d possible server addresses to bind to\n", i); #endif for (addr = servAddr; addr != 0; addr = addr->ai_next) { //if (--i) //continue; // Create a TCP socket servSock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (servSock < 0) continue; // Socket creation failed; try next address // Try to bind to the local address and set socket to listen if ((bind(servSock, addr->ai_addr, addr->ai_addrlen) == 0) && (listen(servSock, MAXPENDING) == 0)) { // Print local address of socket struct sockaddr_storage localAddr; socklen_t addrSize = sizeof(localAddr); if (getsockname(servSock, (struct sockaddr* ) &localAddr, &addrSize) < 0) DieWithPerrorMessage("getsockname() failed"); puts("Binding to "); printSocketAddress((struct sockaddr* ) &localAddr, stdout); fputc('\n', stdout); break; // Bind and listen successful } close(servSock); // Close and try again servSock = -1; } // Free address list allocated by getaddrinfo() freeaddrinfo(servAddr); return servSock; }
void catchAlarm(int ignored) { UDP_SOCKET_INFO *udp_server_socket; u_int8 *buffer; size_t length = 0; ssize_t number_bytes; //Test the frame number if (frame_total <= frame_number) { //Stop the timer stopRTPProgress(); //Initialize the frame number and next frame start value frame_number = 0; next_frame_start = 0; return; } //Construct RTP packet buffer = constructRTPPacket(&length); //Create socket for sending rtp packets udp_server_socket = setupServerUDPSocket(rtp_address, itoa(client_rtp_port)); if (udp_server_socket->socket < 0) { perror("setupServerUDPSocket() failed"); } //display the socket address and port fputs("Sending RTP packet to client ", stdout); printSocketAddress((struct sockaddr*)udp_server_socket->address->ai_addr, stdout, true); //print frame number printf(", frame number: #%u\n", frame_number); //Send the rtp packet number_bytes = sendto(udp_server_socket->socket, buffer, RTP_HEAD_SIZE + length, MSG_NOSIGNAL, udp_server_socket->address->ai_addr, udp_server_socket->address->ai_addrlen); //Test the sending is successful if (number_bytes < 0) { perror("sendto() failed"); } else if (number_bytes != (RTP_HEAD_SIZE + length)) { perror("sendto() error: trying to send unexpected number of bytes!"); } //Close server socket close(udp_server_socket->socket); //Free the _udp_socket_info structure free(udp_server_socket); //Increase the sequence number frame_number++; return; }
/*Handle SIGIO Signal Function Variable Definition: -- signal_type: signal type Return value: NULL */ void SIGIOHandler(int signal){ u_int8 *buffer; //datagram buffer ssize_t number_bytes_rcvd; //size of received message //Allocate memory for buffer buffer = (u_int8*)malloc(sizeof(u_int8) * FRAME_SIZE); //As long as there is input... do{ struct sockaddr_storage server_address; //server address socklen_t server_address_length; //length of server address structure //Set length of server address structure server_address_length = sizeof(server_address); //Block until receive message from a server number_bytes_rcvd = recvfrom( rtp_client, buffer, FRAME_SIZE, 0, (struct sockaddr*)&server_address, &server_address_length); //Receive is failed if (number_bytes_rcvd < 0){ //Only acceptable error: recvfrom() would have blocked if (errno != EWOULDBLOCK){ perror("recvfrom() failed"); return; } } //Receivei is successful else{ //Now, client has received server message //Check the RTP packet header if (checkRTPHeader(buffer)){ //Set the new image on the image widget setImage(buffer); } //Output the server address and port fputs("Receive RTP packet from ", stdout); printSocketAddress((struct sockaddr*)&server_address, stdout); //Output the frame number printf(", frame number: #%u\n", frame_number); } }while (number_bytes_rcvd >= 0); //Nothing left to receive return; }
void sendOblify( enum PacketType type , int port ) { int s; ssize_t n; struct sockaddr_in mySocketAddress = { 0 }; struct sockaddr_in yourSocketAddress = { 0 }; if (( s = socket( AF_INET , SOCK_DGRAM , 0 )) < 0 ) { perror( "socket failed" ); exit( 1 ); } /* if((x = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &arg, sizeof(arg))<0) error("setsockopt SO_BROADCAST"); */ makeLocalSocketAddress( &mySocketAddress ); //printSocketAddress( mySocketAddress ); if ( bind( s , (struct sockaddr *)&mySocketAddress , sizeof(struct sockaddr_in)) != 0) { close( s ); perror( "bind failed" ); exit( 1 ); } makeDestinationSocketAddressFromIP( &yourSocketAddress , port ); printSocketAddress( yourSocketAddress ); if ( (n = sendto( s , (void *)buffer , BUFFERSIZE , 0 , (struct sockaddr *)&yourSocketAddress , sizeof(struct sockaddr_in))) < 0) { perror( "send failed\n" ); exit( 1 ); } close( s ); }
/*Accept Client Connection Function Variable Definition: -- server_socket: server socket number Return Value: connected client socket number */ int acceptConnection(int server_socket){ struct sockaddr_storage client_address; //client address socklen_t client_address_length; //length of client address structure int client_socket; //socket descriptor for client //Set length of client address structure client_address_length = sizeof(client_address); //Wait for a client to connect client_socket = accept(server_socket, (struct sockaddr*)&client_address, &client_address_length); if (client_socket < 0){ dieWithSystemMessage("accept() failed!"); } //Now, client_socket is connected to a client //Output the socket address and port fputs("Handling client ", stdout); printSocketAddress((struct sockaddr*)&client_address, stdout); fputc('\n', stdout); return client_socket; }
/*Main Function Variable Definition: -- argc: the number of command arguments -- argv[]: each vairable of command arguments(argv[0] is the path of execution file forever) Return Value: Client exit number */ int main(int argc, char *argv[]){ //Test for correct number of arguments if (argc != 3){ dieWithUserMessage("Parameter(s)", "<Server Address/Name> <Server Port/Service>"); } struct sigaction handler; //signal handler const char *host = argv[1]; //first argument: host name/ip address const char *service = argv[2]; //second argument: server listening port number int rcvd_buffer_size = 50 * BUFFER_SIZE; //received buffer size //Initialize Pinger initPinger(); //Create a unreliable UDP socket client_socket = setupClientSocket(host, service); if (client_socket < 0){ dieWithSystemMessage("setupClientSocket() failed"); } //Set the received buffer size setsockopt(client_socket, SOL_SOCKET, SO_RCVBUF, &rcvd_buffer_size, sizeof(rcvd_buffer_size)); //Set signal handler for alarm signal handler.sa_handler = catchAlarm; //Blocking everything in handler if (sigfillset(&handler.sa_mask) < 0){ dieWithSystemMessage("sigfillset() failed"); } //No flags handler.sa_flags = 0; //Set the "SIGALRM" signal if (sigaction(SIGALRM, &handler, 0) < 0){ dieWithSystemMessage("sigaction() failed for SIGALRM"); } //Set the "SIGINT" signal if (sigaction(SIGINT, &handler, 0) < 0){ dieWithSystemMessage("sigaction() failed for SIGINT"); } //Output the title printf("PING %s (", host); printSocketAddress((struct sockaddr*)address->ai_addr, stdout); printf(") result:\n"); //Sleep for 1 second sleep(TIMEOUT); //Start to send ping message while (send_count < PING_SIZE){ sendPingMessage(); rcvdPingMessage(TIMEOUT); } //You should put sleep function inside the while loop and after rcvdPingMessage, and you should sleep for TIMEOUT - rtt value for this cycle #13 -4 //Determine that no more replies that comes in if (send_count != rcvd_count){ rcvdPingMessage(REPLY_TIMEOUT); } //SIGINT signal: construct ping statistics catchAlarm(SIGINT); return 0; }