#include #include #include #include #include #include #include #include #include #include #include "scolor.h" void send_count(int skt, uint16_t count){ char report[3]; report[0] = 1; memcpy(report + 1, &count, 2); write(skt, report, 3); } uint16_t get_count(int skt){ char buffer[3]; buffer[0] = 2; write(skt, buffer, 1); recv(skt, buffer, 3, MSG_WAITALL); return *((uint16_t*)(buffer+1)); } int report(uint16_t current_count, uint16_t expected_count){ if(current_count == expected_count){ printf(GREEN("Current count is %u\n"), current_count); return 0; } printf(RED("Current count is %u, expected %u\n"), current_count, expected_count); return 1; } void* client_one(void* param){ int skt = socket(AF_INET, SOCK_STREAM, 0); // Each client has its own socket connect(skt, (struct sockaddr*)param, sizeof(struct sockaddr_in)); report(get_count(skt), 0); send_count(skt, 5); send_count(skt, 5); report(get_count(skt), 10); sleep(2); report(get_count(skt), 510); close(skt); } void* client_two(void* param){ sleep(1); // This test will carefully avoid causing race conditions int skt = socket(AF_INET, SOCK_STREAM, 0); connect(skt, (struct sockaddr*)param, sizeof(struct sockaddr_in)); report(get_count(skt), 10); char bulk_report[300]; for(size_t i = 0; i < 300; i += 3){ bulk_report[i] = 1; *((uint16_t*)(bulk_report + i + 1)) = 5; } write(skt, bulk_report, 300); report(get_count(skt), 510); close(skt); } int main(int argc, char ** argv){ if(argc < 3){ printf("Usage: %s address port\n", argv[0]); return 1; } struct sockaddr_in sad; sad.sin_port = htons(atoi(argv[2])); sad.sin_addr.s_addr = INADDR_ANY; sad.sin_family = AF_INET; struct hostent* entry = gethostbyname(argv[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; pthread_t thread_one, thread_two; pthread_create(&thread_one, 0, client_one, (void*)&sad); pthread_create(&thread_two, 0, client_two, (void*)&sad); pthread_join(thread_one, 0); pthread_join(thread_two, 0); return 0; }