Exemple #1
0
int main(void)
{
	int sockfd;
	/*
	* this is the container for socket's address that contains
	* address family, ip address, port
	*/
	struct sockaddr serv_addr;
	char filler[16] = {0};
	/* just to dump the handle for the spawned thread - no use */
	pthread_t receiver_thread;

	pthread_cond_init(&console_cv, NULL);
	pthread_mutex_init(&console_cv_lock, NULL);

	/*
	* creates a socket of family Internet sockets (AF_INET) and
	* of type stream. 0 indicates to system to choose appropriate
	* protocol (eg: TCP)
	*/
	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	/*
	* Address represented by struct sockaddr:
	* first 2 bytes: Address Family,
	* next 2 bytes: port,
	* next 2 bytes: ipaddr,
	* next 8 bytes: zeroes
	*/
	/*
	* htons() and htonl() change endianness to
	* network order which is the standard for network
	* communication.
	*/
	filler[0] = (unsigned short)AF_INET;
	filler[2] = (unsigned short)htons(port);
	filler[4] = (unsigned long)htonl(INADDR_ANY);

	/* copy data in the filler buffer to the socket address */
	memcpy(&serv_addr, filler, sizeof serv_addr);

	/* binds a socket to an address */
	bind(sockfd, &serv_addr, sizeof serv_addr);

	/* makes connection per the socket address */
	connect(sockfd, &serv_addr, sizeof serv_addr);

	printf("%s\n", "Enter a username (max 20 characters, no spaces):");
	fgets(username, sizeof username, stdin);
	/* fgets also reads the \n from stdin, strip it */
	username[strlen(username) - 1] = '\0';

	register_username(sockfd);
	/* spawn a new thread that continuously listens for any msgs from server */
	pthread_create(&receiver_thread, NULL, receiver, (void*)&sockfd);
	/* get our console in action, let the user enter commands */
	console(sockfd);

	return 0;
}
Exemple #2
0
int main(void)
{
	int sockfd;

	/*
	* struct sockaddr defines a socket address.
	* A socket address is a combination of address family,
	* ip address and port.
	* For IP sockets, we may use struct sockaddr_in which is
	* just a wrapper around struct sockaddr.
	* Funtions like bind() etc are only aware of struct sockaddr.
	*/
	struct sockaddr_in serv_addr;

	/* just to dump the handle for the spawned thread - no use */
	pthread_t receiver_thread;

	pthread_cond_init(&console_cv, NULL);
	pthread_mutex_init(&console_cv_lock, NULL);

	/*
	* creates a socket of family Internet sockets (AF_INET) and
	* of type stream. 0 indicates to system to choose appropriate
	* protocol (eg: TCP)
	*/
	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	/*
	* Socket adddress represented by struct sockaddr:
	* first 2 bytes: Address Family,
	* next 2 bytes: port,
	* next 4 bytes: ipaddr,
	* next 8 bytes: zeroes
	*/
	/*
	* htons() and htonl() change endianness to
	* network order which is the standard for network
	* communication.
	*/

	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	/*
	* The above achieves what could be done using the following
	* on a little endian machine.
	* This breaks if the structure has padding
		char filler[16] = {0};
		filler[0] = AF_INET & 0xFF;
		filler[1] = AF_INET >> 8 & 0xFF;
		filler[2] = htons(port) & 0xFF;
		filler[3] = htons(port) >> 8 & 0xFF;
		filler[4] = htonl(INADDR_ANY) & 0xFF;
		filler[5] = htonl(INADDR_ANY) >> 8 & 0xFF;
		filler[6] = htonl(INADDR_ANY) >> 16 & 0xFF;
		filler[7] = htonl(INADDR_ANY) >> 24 & 0xFF;
		memcpy(&serv_addr, filler, sizeof(serv_addr));
	*/

	/*
	* Note that we do not bind() our socket to any socket adddress here.
	* This is because on the client side, you would only use bind() if you want
	* to use a particular client side port to connect to the server.
	* When you do not bind(), the kernel will pick a port for you.
	* Read here how kernel gets you a port: https://idea.popcount.org/2014-04-03-bind-before-connect
	* There are a few protocols in the Unix world that expect clients to connect from a particular port.
	* Create a new socket address definition and bind it to socket in such cases:
		struct sockaddr_in client_addr;
		client_addr.sin_family = AF_INET;
		client_addr.sin_port = htons(CLIENT_PORT);
		client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
		bind(sockfd, (struct sockaddr*) &client_addr, sizeof client_addr);
	*/

	/* makes connection per the socket address */
	connect(sockfd, (struct sockaddr*) &serv_addr, sizeof serv_addr);

	printf("%s\n", "Enter a username (max 20 characters, no spaces):");
	fgets(username, sizeof username, stdin);
	/* fgets also reads the \n from stdin, strip it */
	username[strlen(username) - 1] = '\0';

	register_username(sockfd);
	/* spawn a new thread that continuously listens for any msgs from server */
	pthread_create(&receiver_thread, NULL, receiver, (void*)&sockfd);
	/* get our console in action, let the user enter commands */
	console(sockfd);

	return 0;
}