// UDP - Listener
// Create a socket and listen on it

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <winsock2.h>
#include "sockerr.h"

#define LISTENON 5000

extern "C"

int main(int argc,char *argv[]) {

	char msg_buf[1024];
	int addr_len;
	int bytes = 0;
	int serv_host_port;
	struct sockaddr_in hostaddr, clientaddr;
	char *serv_host_name;
	struct hostent *hp;
	SOCKET sock,listen_sock;


	if (argc < 2)
		serv_host_port = LISTENON;
	else
		serv_host_port = atoi(argv[1]);

	/* Initializing the Socket Library */
	WSADATA info;
	if (WSAStartup(MAKEWORD(2,2), &info) != 0) {
		psockerr("Error while initializing Socket Library ");
		exit(1);
	}

	/* first get the machine name */
	serv_host_name = (char *) malloc(sizeof(char) * 100);
	if (gethostname(serv_host_name,100) != 0) {
		psockerr(" Get Host name ");
		exit(1);
	} 

	/* Get the address of the host and setup the sockaddr structure */
	if ((hp = gethostbyname(serv_host_name)) == NULL) {
		psockerr("gethostbyname ");
		exit(1);
	}

	memset(&hostaddr,0,sizeof(hostaddr));
	memcpy((char *)&hostaddr.sin_addr,hp->h_addr,hp->h_length);

	hostaddr.sin_family = AF_INET;
	hostaddr.sin_port = htons(serv_host_port);

	/* Create the Socket */
	if ((sock = socket(AF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) {
		psockerr("Unable to create Socket ");
		exit(1);
	}

	addr_len = sizeof(sockaddr_in);

	if (bind(sock,(sockaddr *)&hostaddr,addr_len) == SOCKET_ERROR) {
		psockerr("Unable to bind ");
		closesocket(sock);
		exit(1);
	}

	printf("UDP Server Listening on port #%d\n\n",serv_host_port);

	while ((bytes = recvfrom(sock,msg_buf,1024,0,(sockaddr *)&clientaddr,&addr_len)) > 0) {
		msg_buf[bytes] = '\0';
		if ((hp = gethostbyaddr((char *)&clientaddr.sin_addr,sizeof(in_addr),AF_INET)) == NULL) {
			psockerr("Get Host by addr ");
			exit(1);
		}
		printf("Received From : %s (IP : %s)\n",hp->h_name,inet_ntoa(clientaddr.sin_addr));
		printf("Recv : %s\n",msg_buf);
	}

	closesocket(sock);

	return 0;
}