コード例 #1
0
ファイル: client.c プロジェクト: csdaiwei/netlab03
/*a thread created after login, to receive all packets from server
 *the main thread will no more receive packet after this thread created*/
void *
recv_packet_thread(void *this_is_no_use){

	int n = 0;	//number received 
	while( (n = readvrec(client_sock, recvbuf, BUF_SIZE)) > 0){
		struct im_pkt_head *response_head = (struct im_pkt_head *)recvbuf;
		char *response_data = (char *)(response_head + 1);
		//struct im_pkt_head *response_head = (struct im_pkt_head *)sendbuf;
		//int response_data_size;
		//printf("debug:received a packet from socket:%d, type:%d, service:%d, data size:%d\n"
		//	, client_socket, request_head -> type, request_head -> service, request_head -> data_size);

		memset(sendbuf, 0, sizeof(sendbuf));
		if(response_head -> type != TYPE_RESPONSE){
			printf("\nReceived a error packet, drop it.\n enter >> ");
			break;
		}
		switch(response_head -> service){
			/*case SERVICE_LOGIN: ;
				break;
			case SERVICE_LOGOUT: ;
				break;
			case SERVICE_QUERY_ONLINE: ;
				break;*/
			case SERVICE_SINGLE_MESSAGE: ;
				char *sender = response_data;
				char *text = response_data + 40;/*two names' length*/
				printf("\nMessage comes from %s:\n \t%s\nenter >> ", sender,text);
				fflush(stdout);
				save_recent_messages(sender, text);
				break;
			case SERVICE_MULTI_MESSAGE: ;
				sender = response_data;
				text = response_data + 20;/*one name's length*/
				printf("\nMessage comes from %s:\n \t%s\nenter >> ", sender,text);
				fflush(stdout);
				save_recent_messages(sender, text);
				break;
			case SERVICE_ONLINE_NOTIFY: ;
				char *that_online_username = response_data;
				if(find_user_by_name(online_friend_queue, that_online_username) == NULL){
					struct user_node *n = init_user_node(-1, that_online_username);
					enqueue(online_friend_queue, n);
				}
				break;
			case SERVICE_OFFLINE_NOTIFY: ;
				char *that_offline_username = response_data;
				delete_user_by_name(online_friend_queue, that_offline_username);
				break;
			default:
				printf("\nReceived a error packet, drop it.\n enter >> ");break;
		}
		memset(recvbuf, 0, sizeof(recvbuf));
	}
	if( n < 0)
		printf("Read error\n");
	pthread_exit(NULL);
}
コード例 #2
0
ファイル: ui.c プロジェクト: trailofbits/cb-multios
pUser find_user(char *nameNum, pDataStruct workingData){
	pUser tempUser = NULL;
	int tempNum = strict_atoi(nameNum);
	if (    (  ( strcmp(nameNum,"root") ) && ( strcmp(nameNum,"0") )  ) == 0    ){
		return workingData->user;
	}
	if ( tempNum != 0 ){
		tempUser = find_user_by_number( tempNum, workingData );
		if ( tempUser != NULL ){
			return tempUser;
		}
	}

	tempUser = find_user_by_name( nameNum, workingData);
	return tempUser;
}	
コード例 #3
0
ファイル: server.c プロジェクト: csdaiwei/netlab03
void 
*client_handler(void * connfd){

	int n;	/*number received*/
	char username[20];	//the user's name connecting to this thread. will be filled when login
	int status = -1;	//the user's status
	int client_socket = (int)connfd;	//the user's socket connecting to this thread;
	//debug://long tid = pthread_self();

	assert(online_user_queue != NULL);
		
	/*each thread has its own buf*/
	char sendbuf[BUF_SIZE];
	char recvbuf[BUF_SIZE];
	
	//printf("debug:thread %lu created for dealing with client requests\n", tid);

	/*Receive the request im packet by two steps.
	 *Firstly receive the head field, secondly receive the data field.
	 *Then handle the request packet (usually by a response packet)*/
	while( (n = readvrec(client_socket, recvbuf, BUF_SIZE)) > 0){
		struct im_pkt_head *request_head = (struct im_pkt_head *)recvbuf;
		struct im_pkt_head *response_head = (struct im_pkt_head *)sendbuf;
		char *request_data = (char *)(request_head + 1);
		int response_data_size = 0;
		//printf("debug:received a packet from socket:%d, type:%d, service:%d, data size:%d\n"
		//	, client_socket, request_head -> type, request_head -> service, request_head -> data_size);

		memset(sendbuf, 0, sizeof(sendbuf));
		if(request_head -> type != TYPE_REQUEST){
			printf("Received a error packet, drop it.\n");
			break;
		}
		
		switch(request_head -> service){
			case SERVICE_LOGIN: ;
				/*response a login response packet, 
				 *it contains only 1 byte data to indicate that login succeeded or failed*/
				response_data_size = 1;
				bool login_result;
				strncpy(username, (char *)(request_head + 1), 20);
				
				//check repeat
				pthread_mutex_lock(&mutex);
				if(find_user_by_name( online_user_queue, username) == NULL){
					//printf("debug:here2\n");
					struct user_node *pnode = init_user_node(client_socket, username);
					enqueue(online_user_queue, pnode);
					status = ONLINE_STATUS;
					printf("\tuser %s login.\n", username);
					login_result = true;
					/*notify all othre users*/
					on_off_line_notify(SERVICE_ONLINE_NOTIFY, username, sendbuf);
				}
				else{
					login_result = false;
				}
				pthread_mutex_unlock(&mutex);
				//printf("debug: thread %lu release lock\n", tid);
				construct_im_pkt_head(response_head, TYPE_RESPONSE, SERVICE_LOGIN, response_data_size);
				concat_im_pkt_data(response_head, (char *)&login_result);
				send(client_socket, sendbuf, IM_PKT_HEAD_SIZE + response_data_size, 0);
				//printf("debug:response packet send to socket:%d, type:%d, service:%d, data size:%d\n"
				//	, client_socket, response_head -> type, response_head -> service, response_head -> data_size);
				break;
			case SERVICE_LOGOUT: ;
				/*nothing need to do here.*/
				break;
			case SERVICE_QUERY_ONLINE: ;

				/*copy all usernames into the data field of the response packet*/
				pthread_mutex_lock(&mutex);
				response_data_size = 20 * copy_all_user_name((char *)(response_head + 1), online_user_queue);
				pthread_mutex_unlock(&mutex);
				construct_im_pkt_head(response_head, TYPE_RESPONSE, SERVICE_QUERY_ONLINE, response_data_size);
				/*send the packet*/
				send(client_socket, sendbuf, IM_PKT_HEAD_SIZE + response_data_size, 0);
				break;
			case SERVICE_SINGLE_MESSAGE: ;
				//printf("debug: sender %s, recipient %s, text %s\n", request_data, request_data + 20, request_data + 40);
				/*simple resend the packet to the recipient*/
				char *recipient = request_data + 20;
				struct user_node *recipient_node = find_user_by_name(online_user_queue, recipient); 
				if(recipient_node != NULL){
					response_data_size = request_head -> data_size;
					construct_im_pkt_head(response_head, TYPE_RESPONSE, SERVICE_SINGLE_MESSAGE, response_data_size);
					concat_im_pkt_data(response_head, request_data);
					send(recipient_node -> socket, sendbuf,IM_PKT_HEAD_SIZE + response_data_size, 0);
				}else
					printf("Error, no recipient %s. drop the packet\n", recipient);
				break;
			case SERVICE_MULTI_MESSAGE: ;
				//printf("debug: sender %s, recipient all, text %s\n", request_data, request_data + 20);
				response_data_size = request_head -> data_size;
				construct_im_pkt_head(response_head, TYPE_RESPONSE, SERVICE_MULTI_MESSAGE, response_data_size);
				concat_im_pkt_data(response_head, request_data);
				char *sender = request_data;
				/*send to all online users except this message's sender*/
				for(recipient_node = online_user_queue -> front; recipient_node != NULL; recipient_node = recipient_node -> next)
					if(strcmp(recipient_node -> username, sender) != 0)
						send(recipient_node -> socket, sendbuf,IM_PKT_HEAD_SIZE + response_data_size, 0);
				break;
			default:
				printf("Received a error packet, drop it.\n");break;
		}
		memset(recvbuf, 0, sizeof(recvbuf));
	}
	if( n < 0)
		printf("Read error\n");

	if(status == ONLINE_STATUS){
		/*remove logout or disconnected  users from the queue*/
		on_off_line_notify(SERVICE_OFFLINE_NOTIFY, username, sendbuf);
		pthread_mutex_lock(&mutex);
		delete_user_by_name(online_user_queue, username);
		pthread_mutex_unlock(&mutex);
		status = -1;
		printf("\tuser %s logout\n", username);
	}
	pthread_exit(NULL);
}
コード例 #4
0
ファイル: client.c プロジェクト: csdaiwei/netlab03
int 
main(void){

	struct sockaddr_in server_addr;//server address
	
	/*client start preparations*/
	if((client_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		printf("error create socket\n");
		exit(-1);
	}	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(SERV_PORT);//the weather server port
	inet_pton(AF_INET, SERV_IP, &server_addr.sin_addr.s_addr);//weather server ip address
	if(connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1){
		printf("error connect\n");
		exit(-1);
	}
	online_friend_queue = init_user_queue();
	
	//load login page
	login();

	/*after login, the username and current online friends list will be settled down*/
	/*create a thread to receive packets asynchronously */
	pthread_t tid;
	int rc = pthread_create(&tid, NULL, recv_packet_thread, NULL);
	if(rc){
		printf("ERROR creating thread, tid %d, return code %d\n", (int)tid, rc);
		exit(-1);
	}

	/*main thread loads the next page to get user's command*/
	if(system("clear")) ;
	print_prompt_words(username);
	while(true){
		printf("enter >> ");
		char command[20];
		get_keyboard_input(command, 20);
		//printf("debug:%s\n", command);
		if(command[0] != '-'){
			printf("input error, you can try again.\n");
			continue;
		}
		if(strcmp(&command[1], "list") == 0) {
			assert(online_friend_queue -> front != NULL);
			print_online_friends(online_friend_queue);
			continue;

		} else if(strcmp(&command[1], "clear") == 0){
			if(system("clear")) ;
			print_prompt_words(username);
			continue;

		} else if(strcmp(&command[1], "logout") == 0){
			logout();
			break;//this lead to the end of the program.

		} else if(strcmp(&command[1], "recent") == 0){
			print_recent_messages(recent_messages, message_num);
			continue;
		}else if(strcmp(&command[1], "chat") == 0){
			/*bug:if someone's name is "all", bug happens*/
			char recipient[20];
			printf("Who do you want to talk to?\n" 
				"Type he/she's name or type \"all\":");
			get_keyboard_input(recipient, 20);
			if(strcmp(recipient, username) == 0){
				printf("it's funny to talk to yourself.\n");
			} 
			else if(strcmp(recipient, "all") == 0){
				char text[100];
				printf("Input your words to say to %s.\n"
					   "Within 100 characters, end up with the Enter key):\n", recipient);
				get_keyboard_input(text, 100);

				/*build and send the packet*/
				memset(sendbuf, 0, sizeof(sendbuf));
				unsigned short data_size = 20 + 100;
				construct_im_pkt_head((struct im_pkt_head *)sendbuf, TYPE_REQUEST, SERVICE_MULTI_MESSAGE, data_size);
				strncpy(&sendbuf[IM_PKT_HEAD_SIZE], username, 20);
				strncpy(&sendbuf[IM_PKT_HEAD_SIZE + 20], text, 100);
				send(client_sock, sendbuf, IM_PKT_HEAD_SIZE + data_size, 0);
			} else if(find_user_by_name(online_friend_queue, recipient) != NULL){
				//printf("debug:%s\n", recipient);

				char text[100];
				printf("Input your words to say to %s.\n"
					   "Within 100 characters, end up with the Enter key):\n", recipient);
				get_keyboard_input(text, 100);

				/*build and send the packet*/
				memset(sendbuf, 0, sizeof(sendbuf));
				unsigned short data_size = 20 + 20 + 100;
				construct_im_pkt_head((struct im_pkt_head *)sendbuf, TYPE_REQUEST, SERVICE_SINGLE_MESSAGE, data_size);
				strncpy(&sendbuf[IM_PKT_HEAD_SIZE], username, 20);
				strncpy(&sendbuf[IM_PKT_HEAD_SIZE + 20], recipient, 20);
				strncpy(&sendbuf[IM_PKT_HEAD_SIZE + 40], text, 100);
				send(client_sock, sendbuf, IM_PKT_HEAD_SIZE + data_size, 0);

			} else{
				printf("sorry, %s seems not online now\n", recipient);
				print_online_friends(online_friend_queue);
			}
			continue;
		}  else{
			printf("input error, you can try again.\n");
			continue;	
		}
	}
	/*close socket and stop another thread before exit*/
	pthread_cancel(tid);
	close(client_sock);
	return 0;
}