/*************WSOCKSRV.C******************* SOCKET SERVER (Fischetti P.) ****************************************/ #undef UNICODE #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #pragma comment (lib, "Ws2_32.lib") #define DEFAULT_BUFLEN 1024 #define DEFAULT_PORT "27000" void handler_quit(int signal){ fprintf(stderr,"BYE!\n"); WSACleanup(); exit(0); } int help(char *proc) { fprintf(stderr,"\t*** SOCKET SERVER\t(By Fischetti P.) ***\n\n"); fprintf(stderr,"Syntax:\n\t"); fprintf(stderr,"%s [-pPORT(%s)]\n",proc,DEFAULT_PORT); return -1; } // dumps raw memory in hex byte and printable split format void dump(const unsigned char *data_buffer, const unsigned int length) { unsigned char byte; unsigned int i, j; for(i=0; i < length; i++) { byte = data_buffer[i]; printf("%02x ", data_buffer[i]); // display byte in hex if(((i%16)==15) || (i==length-1)) { for(j=0; j < 15-(i%16); j++) printf(" "); printf("| "); for(j=(i-(i%16)); j <= i; j++) { // display printable bytes from line byte = data_buffer[j]; if((byte > 31) && (byte < 127)) // outside printable char range printf("%c", byte); else printf("."); } printf("\n"); // end of the dump line (each line 16 bytes) } // end if } // end for } char buff[512]={0}; int getArg(char *str, char *arg, char *out){ char *pch = strstr(str, arg); int string_size=0; if (pch!=NULL){ strncpy(out,pch+strlen(arg),7); return 1; } return 0; } int ExistArg(char *str, char *arg){ char *pch = strstr(str, arg); return pch!=NULL; } char* ReadHTMLFile(const char *filename) { char *buffer = NULL; int string_size, read_size; FILE *handler = fopen(filename, "rb"); if (handler) { // Seek the last byte of the file fseek(handler, 0, SEEK_END); // Offset from the first to the last byte, or in other words, filesize string_size = ftell(handler); // go back to the start of the file rewind(handler); // Allocate a string that can hold it all buffer = (char*) malloc(sizeof(char) * (string_size + 1) ); // Read it all in one operation read_size = fread(buffer, sizeof(char), string_size, handler); // fread doesn't set it so put a \0 in the last position // and buffer is now officially a string buffer[string_size] = '\0'; if (string_size != read_size) { fprintf(stderr, "%d %d Something went wrong, throw away the memory and set the buffer to NULL\n",string_size, read_size); free(buffer); buffer = NULL; } // Always remember to close the file. fclose(handler); } else fprintf(stderr,"Error on Opening File:%s\n",filename); return buffer; } void PrintError(const char *msg,DWORD err) { if(msg) fprintf(stderr,"%s%d\n",msg,err); //DWORD err = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); fprintf(stderr,"WIN Last Error: %s" , (LPCTSTR)lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); } int main(int argc, char **argv) { WSADATA wsaData; int iResult; const char *cExit="&"; char banner[1024]={0}; int i; char port[6]={0}; strcpy(port,DEFAULT_PORT); for (i = 1; i < argc; i++) { if (('-' == argv[i][0]) || ('/' == argv[i][0])) { char cp; cp = argv[i][1]; switch (cp) { case 'P': case 'p': { strncpy(port, &argv[i][2], sizeof(port)); } break; case 'h': case '?': default: return help(argv[0]); } } } SOCKET ListenSocket = INVALID_SOCKET; SOCKET ClientSocket = INVALID_SOCKET; struct sockaddr_in caddr; int clientLen; signal(SIGINT,handler_quit); signal(SIGABRT,handler_quit); struct addrinfo *result = NULL; struct addrinfo hints; int iSendResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { PrintError("WSAStartup failed with error: ", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; // Resolve the server address and port iResult = getaddrinfo(NULL, port, &hints, &result); if ( iResult != 0 ) { PrintError("getaddrinfo failed with error: ", iResult); WSACleanup(); return 1; } fprintf(stderr,"Listen on Port:%s\n",port); // Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { PrintError("socket failed with error: ", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } // Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { PrintError("bind failed with error: ", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; } freeaddrinfo(result); iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { PrintError("listen failed with error: ", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } for (;;){ // Accept a client socket fprintf(stderr,"Wait for connection...\n"); //printf("pointer: %p\n",&caddr); clientLen = sizeof(struct sockaddr_in); ClientSocket = accept(ListenSocket, (struct sockaddr *)&caddr, &clientLen); if (ClientSocket == INVALID_SOCKET) { PrintError("accept failed with error: ", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; } fprintf(stderr,"Hello client %s port %d (%s to quit)\n",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),cExit ); // Receive until the peer shuts down the connection do { iResult = recv(ClientSocket, recvbuf, recvbuflen, 0); if (iResult > 0) { recvbuf[iResult]=0; fprintf(stderr,"Bytes received: %d %s\n", iResult,recvbuf); /////dump(recvbuf,sizeof(recvbuf)); if(strncmp(recvbuf,"GET / HTTP/1.1",strlen("GET / HTTP/1.1"))==0){ char *str=ReadHTMLFile("index.html"); if(str){ //strcpy(banner,"HTTP/1.1 200\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n",strlen(str));//Connection: close\r\nContent-Length: 0\r\n sprintf(banner,"HTTP/1.1 200\r\nContent-Type: text/html\r\nConnection: keep-alive\r\nContent-Length: %d\r\n\r\n",(int)strlen(str)); strcat(banner,str); send( ClientSocket, banner, sizeof(banner), 0 ); iSendResult=strlen(banner); free(str); } else{ sprintf (banner, "Hello client %s port %d (%s to quit)",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),cExit ); send( ClientSocket, str, sizeof(banner), 0 ); iSendResult=strlen(str); } } else if(strncmp(recvbuf,"POST / HTTP/1.1",strlen("POST / HTTP/1.1"))==0){ char *str=ReadHTMLFile("index.html"); if(str){ sprintf(banner,"HTTP/1.1 200\r\nContent-Type: text/html\r\nConnection: keep-alive\r\nContent-Length: %d\r\n\r\n",(int)strlen(str)); strcat(banner,str); send( ClientSocket, banner, sizeof(banner), 0 ); iSendResult=strlen(banner); free(str); int ipch=getArg(recvbuf,"arg=",buff); if(ipch){ fprintf(stderr,"%s\n",buff); printf("%s\n",buff); fflush(stdout); } } else{ sprintf (banner, "Hello client %s port %d (%s to quit)",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),cExit ); send( ClientSocket, str, sizeof(banner), 0 ); iSendResult=strlen(str); } } // Echo the buffer back to the sender else iSendResult = send( ClientSocket, recvbuf, iResult, 0 ); if (iSendResult == SOCKET_ERROR) { PrintError("send failed with error: ", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } fprintf(stderr,"Bytes sent: %d\n", iSendResult); if(strcmp(recvbuf,cExit)==0){ iResult=0; fprintf(stderr,"Connection Closed\n"); } } else if (iResult == 0) fprintf(stderr,"Connection closing...\n"); else { PrintError("recv failed with error: ", WSAGetLastError()); closesocket(ClientSocket); WSACleanup(); return 1; } } while (iResult > 0); // shutdown the connection since we're done iResult = shutdown(ClientSocket, SD_SEND); if (iResult == SOCKET_ERROR) { PrintError("shutdown failed with error: ", WSAGetLastError()); closesocket(ClientSocket); } } // cleanup closesocket(ClientSocket); WSACleanup(); return 0; }