Example #1
0
int main(void) {
	struct UDPsopa sopa = {
		.sop = NULL,
		.pap = NULL,
		.port        = 0, // 0 = pick unused port
		.packet_size = 512,
		.packet_num  = 0,
		.host_port   = 4444
	};
	strcpy(sopa.host_name, "127.0.0.1");
	if (udp_setup(&sopa) != 0) {
		udp_cleanup(&sopa);
		exit(EXIT_FAILURE);
	}

	// additional client setup
	if (SDLNet_ResolveHost(&(sopa.pap->address), sopa.host_name, sopa.host_port) != 0) {
		printf("SDLNet_ResolveHost(&(sopa.pap->address), sopa.host_name, sopa.host_port) != 0\n");
		printf("SDLNet_GetError() = '%s'\n", SDLNet_GetError());
		udp_cleanup(&sopa);
		exit(EXIT_FAILURE);
	}

	srand(123);
	for (;;) {
		sleep(1); // 1 second
		sprintf((char*)sopa.pap->data, "rand_num = %d", rand());
		sopa.pap->len = strlen((char*)sopa.pap->data) + 1;

		const int channel = -1; // -1 = use packet's address as destination
		if (SDLNet_UDP_Send(sopa.sop, channel, sopa.pap) == 0) {
			printf("SDLNet_UDP_Send(sopa.sop, channel, sopa.pap) == 0\n");
			printf("SDLNet_GetError() = '%s'\n", SDLNet_GetError());
			udp_cleanup(&sopa);
			exit(EXIT_FAILURE);
		}

		switch (SDLNet_UDP_Recv(sopa.sop, sopa.pap)) {
		case -1:
			printf("SDLNet_UDP_Recv(sopa.sop, sopa.pap) == -1\n");
			printf("SDLNet_GetError() = '%s'\n", SDLNet_GetError());
			udp_cleanup(&sopa);
			exit(EXIT_FAILURE);
		case 0:
			printf("SDLNet_UDP_Recv(sopa.sop, sopa.pap) == 0 // no packets received\n");
			break;
		case 1:
			sopa.packet_num++;
			udp_print(&sopa);
			break;
		}
	} // for(;;)

	udp_cleanup(&sopa);
	exit(EXIT_SUCCESS);
}
Example #2
0
void send_test(void)
{
	u32 ip = ((u32)192 << 24) | ((u32)168 << 16) | ((u32)1 << 8) | 20;
	u16 src_port;
	u16 port = 8888;
	char data[] = "hello world!";
	u16 len;

	udp_close(0);
	
	if (udp_setup(ip, port, port) < 0)
		err_log("udp_setup");
	
	send_data(ip, port, port, data, strlen(data));
	
	recv_data(&ip, &src_port, data_i, &len);
}
Example #3
0
int main(int argc, char **argv)
{
	int udp_socket;
	int tcp_socket;
	int tcp_port;

	int client_socket;

	struct sockaddr_in addr;
	int addr_size;

	char buffer[1025];

	struct client *clients;

	int num_clients;
	int max_clients;

	int i, j;
	int len;
	char* temp_str;

	fd_set read_fds_master;
	fd_set read_fds_copy;
	int fd_max;

	FD_ZERO(&read_fds_master);
	FD_ZERO(&read_fds_copy);

	clients = malloc(BACKLOG * sizeof(struct client));
	num_clients = 0;
	max_clients = BACKLOG;

	
	/* signal(SIGINT, handle_sigint); */


	if ((udp_socket = udp_setup(UDP_PORT)) == -1) exit(1);

	/* make udp socket "select()able" */
	FD_SET(udp_socket, &read_fds_master);
	fd_max = udp_socket;

	if((tcp_socket = tcp_setup(&tcp_port)) == -1) exit(1);
	printf("Listening on tcp port: %d\n", tcp_port);

	/* make tcp socket "select()able" */
	FD_SET(tcp_socket, &read_fds_master);
	fd_max = tcp_socket;


	/* main loop */
	for (;;)
	{
		/* handle readable sockets */
		read_fds_copy = read_fds_master; // make a copy that select() can modify
		if (select(fd_max + 1, &read_fds_copy, NULL, NULL, NULL) == -1)
		{
			fprintf(stderr, "Error during select().\n");
			close(udp_socket);
			exit(1);
		}

		for (i = 0; i <= fd_max; i++)
		{
			if (FD_ISSET(i, &read_fds_copy))
			{
				if (i == udp_socket)
				{
					/* answer a multicast message */
					memset(buffer, 0, sizeof(buffer));
					addr_size = sizeof(addr);
					if (recvfrom(udp_socket, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addr_size) == -1)
					{
						fprintf(stderr, "Error receiving multicast message.\n");
						close(udp_socket);
						exit(1);
					}


					if (strncmp(buffer, "server_discovery", 16) == 0)
					{
						printf("%s:%d - discovery request\n", inet_ntoa(addr.sin_addr.s_addr), ntohs(addr.sin_port));
						len = sprintf(buffer, "discovery_reply %d\n", tcp_port);
						addr_size = sizeof(addr);
						if (sendto(udp_socket, buffer, len, 0, (struct sockaddr*)&addr, addr_size) == -1)
						{
							perror("Error answering multicast message.\n");
							close(udp_socket);
							exit(1);
						}
					}
				}
				if (i == tcp_socket)
				{
					for (j = 0; j < num_clients; j++)
					{
						if (clients[j].status == 'd') break; /* the value of j at this point is used as a side effect later */
					}
					/* j is now ALWAYS the first unused index of the clients array */
					if (j == num_clients) num_clients++;

					if (num_clients > max_clients)
					{
						max_clients = max_clients + BACKLOG;
						clients = realloc(clients, max_clients * sizeof(struct client));
					}
					addr_size = sizeof(addr);
					clients[j].socket = accept(tcp_socket, (struct sockaddr*)&addr, &addr_size);
					clients[j].status = 'c';

					/* save source as string for logging and debugging */
					strncpy(clients[j].socket_addr, (const char*)inet_ntoa(addr.sin_addr.s_addr), 15);
					clients[j].socket_port = ntohs(addr.sin_port);
					printf("%s:%d - new connection.\n", clients[j].socket_addr, clients[j].socket_port);
					FD_SET(clients[j].socket, &read_fds_master);
					if (clients[j].socket > fd_max) fd_max = clients[j].socket;
				}
				for (j = 0; j < num_clients; j++)
				{
					if (i == clients[j].socket)
					{
						memset(buffer, 0, sizeof(buffer));
						len = recv(clients[j].socket, buffer, sizeof(buffer) - 1 - strlen(clients[j].line_buffer), 0);
						switch (len)
						{
						case 0:
							printf("%s:%d - disconnected.\n", clients[j].socket_addr, clients[j].socket_port);
							FD_CLR(clients[j].socket, &read_fds_master);
							clients[j].status = 'd';
							push_global_filelist(clients, num_clients);
							break;
						case -1:
							/* TODO: handle gracefully. this is usually a "connection reset by peer" */
							perror("recv");
							break;
						default:
							strncat(clients[j].line_buffer, buffer, len);

							while (strchr(clients[j].line_buffer, '\n') != NULL)
							{
								switch (clients[j].status)
								{
								case 'c':
									//printf("status: connected\n");
									if (sscanf(clients[j].line_buffer, "register %d", &(clients[j].download_port)) == 1)
									{
										printf("%s:%d - registered port %d for downloads.\n", clients[j].socket_addr, clients[j].socket_port, clients[j].download_port);
										clients[j].status = 'r';
										break;
									}
									printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
									break;
								case 'r':
									//printf("status: registered\n");
									//printf("buffer: %s", clients[j].line_buffer);
									if (sscanf(clients[j].line_buffer, "send_filelist %d\n", &(clients[j].filelist_size)) == 1)
									{
										if (clients[j].filelist_size > 0)
										{
											printf("%s:%d - will send %d file list entries next.\n", clients[j].socket_addr, clients[j].socket_port, clients[j].filelist_size);
											if (clients[j].file_list != NULL) free(clients[j].file_list);
											clients[j].file_list = malloc(clients[j].filelist_size * sizeof(struct filelist_entry));
										}

										clients[j].status = 's';
										clients[j].filelist_len = 0;
									break;
									}
									if (strncmp(clients[j].line_buffer, "unregister", 10) == 0)
									{
										printf("%s:%d - unregistered download port.\n", clients[j].socket_addr, clients[j].socket_port);
										clients[j].status = 'c';
										break;
									}
									printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
									break;
								case 's':
									//printf("status: sending file list\n");
									if (clients[j].filelist_len < clients[j].filelist_size)
									{	
										len = clients[j].filelist_len;
										if (sscanf(clients[j].line_buffer , "%d %1000s", &(clients[j].file_list[len].size), clients[j].file_list[len].name) == 2)
										{
											clients[j].filelist_len = clients[j].filelist_len + 1;
											printf("%s:%d - sent a file list entry: %s (%d bytes)\n", clients[j].socket_addr, clients[j].socket_port, clients[j].file_list[len].name, clients[j].file_list[len].size);

										}
										else
										{
											printf("%s:%d - sent %d unrecognized bytes: %s\n", clients[j].socket_addr, clients[j].socket_port, strlen(clients[j].line_buffer), clients[j].line_buffer);
										}
									}
									if (clients[j].filelist_len == clients[j].filelist_size)
									{
										clients[j].status = 'r';
										push_global_filelist(clients, num_clients);
									}
									break;
								default:
									break;
								}

								/* consume part of buffer */
								temp_str = strchr(clients[j].line_buffer, '\n');
								//printf("bytes left: %d\n", strlen(temp_str));
								if (strlen(temp_str) > 1)
								{
									memset(buffer, 0, sizeof(buffer));
									strncpy(buffer, temp_str + 1, strlen(temp_str) - 1);
									//printf("bytes left: %d\n", strlen(buffer));
									memset(clients[j].line_buffer, 0, sizeof(clients[j].line_buffer));
									strncpy(clients[j].line_buffer, buffer, strlen(buffer));
									//printf("line buffer: %s", clients[j].line_buffer);
								}
								else
								{
									memset(clients[j].line_buffer, 0, sizeof(clients[j].line_buffer));
								}
							}
						}
					}
				}
			}
		}
	}
}