// Run like this: simple_client address port // Results in argv ["./simple_client", "address", "port"] #include #include #include #include #include #include #include #include int main(int argc, char ** argv){ if(argc < 3){ printf("Usage: %s hostname port\n", argv[0]); return 1; } struct sockaddr_in sad; sad.sin_port = htons(atoi(argv[2])); sad.sin_family = AF_INET; int skt = socket(AF_INET, SOCK_STREAM, 0); // do a dns lookup struct hostent* entry = gethostbyname(argv[1]); if(!entry){ if(h_errno == HOST_NOT_FOUND){ printf("This is our own message that says the host wasn't found\n"); } herror("gethostbyname"); return 1; } struct in_addr **addr_list = (struct in_addr**)entry->h_addr_list; struct in_addr* c_addr = addr_list[0]; char* ip_string = inet_ntoa(*c_addr); sad.sin_addr = *c_addr; // copy the address we found into sad // Finally done with DNS! printf("Connecting to: %s\n", ip_string); if( connect(skt, (struct sockaddr*)&sad, sizeof(struct sockaddr_in)) ){ perror("connect"); return 1; } /* This part would read a version uint8_t message[64]; ssize_t actual_length = recv(skt, message, 5, MSG_WAITALL); if(message[0] == 14) printf("Received %ld bytes: type %d, version %d.%d\n", actual_length, message[0], message[1], message[2]); else printf("Got %d which is not a version\n", message[0]); */ // Method 1: Call read a bunch of times /* uint8_t type; read(skt, &type, 1); printf("Type: %d\n", type); uint16_t next_number; read(skt, &next_number, 2); printf("Initial Points: %d\n", next_number); next_number; read(skt, &next_number, 2); printf("Stat Limit: %d\n", next_number); next_number; read(skt, &next_number, 2); printf("Description Length: %d\n", next_number); char description[next_number]; read(skt, description, next_number); printf("Description: %s\n", description); */ // Method 2: Read it all into a buffer of uint8_t /* #define BUFFERSIZE 70000 uint8_t general_buffer[BUFFERSIZE]; ssize_t readlen = 0; readlen += read(skt, general_buffer + readlen, BUFFERSIZE); printf("readlen = %d\n", readlen); if(readlen >= 1){ printf("Type: %d\n", general_buffer[0]); } else { printf("Failed to read even one byte, giving up!\n"); return 1; } uint16_t description_length; while(readlen < 7){ ssize_t addition = read(skt, general_buffer + readlen, BUFFERSIZE); if(addition < 1) { printf("We're disconnected, giving up!\n"); return 1; } readlen += addition; printf("readlen = %d\n", readlen); } if(readlen >= 7){ // Should be true for sure uint16_t initial_points = *((uint16_t*)(general_buffer + 1)); printf("Initial Points: %d\n", initial_points); printf("Stat Limit: %d\n", *((uint16_t*)(general_buffer + 3))); description_length = *((uint16_t*)(general_buffer + 5)); printf("Description Length: %d\n", description_length); } while(readlen < 7 + description_length){ ssize_t addition = read(skt, general_buffer + readlen, BUFFERSIZE); if(addition < 1) { printf("We're disconnected, giving up!\n"); return 1; } readlen += addition; printf("readlen = %d\n", readlen); } if(readlen >= 7 + description_length){ general_buffer[7 + description_length] = 0; printf("Description: %s\n", general_buffer + 7); } */ // Method 3: Match up the data with a C struct struct lurk_game_message { uint8_t type; uint16_t initial_points, stat_limit, description_length; char *description; } __attribute__((packed)); // Otherwise the compiler will leave padding struct lurk_game_message lgm; printf("Size of lgm: %d\n", sizeof(lgm)); ssize_t readlen = recv(skt, &lgm, 7, MSG_WAITALL); printf("readlen = %d\n", readlen); if(readlen < 7){ printf("Failed to read first 7 bytes, giving up!\n"); return 1; } lgm.description = (char*)malloc(lgm.description_length + 1); lgm.description[lgm.description_length] = 0; readlen = recv(skt, lgm.description, lgm.description_length, MSG_WAITALL); if(readlen != lgm.description_length){ printf("Failed to read description, giving up\n"); free(lgm.description); return 1; } printf("Type: %d\n", lgm.type); printf("Initial Points: %d\n", lgm.initial_points); printf("Stat Limit: %d\n", lgm.stat_limit); printf("Description Length: %d\n", lgm.description_length); printf("Description: %s\n", lgm.description); free(lgm.description); close(skt); return 0; }