⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sk.c

📁 linux下一个聊天工具代码
💻 C
字号:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
//#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>

#include "sk.h"
#include "qqproto.h"
#include "friendlist.h"

int sockfd;
fd_set readfds;
int max_fd;
unsigned long local_ip;
unsigned char server_ip[16] = "202.96.170.164"; 
extern unsigned long id;
extern char passwd[PASSWD_MAX];
extern int state;

struct cmd_type
cmds[] = {
        {2, "login", login, NULL},
        {2, "msg", msg, NULL},
        {0, "logoff", logoff, NULL},
        {0, "quit", quit, NULL},
        {0, NULL, NULL}
};




int login(char **options) 
{
	id = (unsigned long)atoi(options[0]);
	strncpy(passwd, options[1] ,PASSWD_MAX);
	    
	passwd[strlen(passwd) - 1] = 0; /* get rid of the trailing newline */

	printf("id = %ld\n", id);
	printf("pass = %s\n", passwd);
    	qqproto_init(id,passwd);
    	send_login();
	return 1;
}

int msg(char **options)
{
	int i;
	char msg[LINE_MAX];
	unsigned long destid;

	destid = (unsigned long)atoi(options[0]);

	msg[0] = '\0';
	for (i = 1; options[i]; ++i) {
		strcat(msg, options[i]);
		msg[strlen(msg) + 1] = '\0';
		msg[strlen(msg)] = ' ';
	}

	printf("destid = %ld\n", destid);
	printf("message = %s\n", msg);

	//send_message_2p(destid,msg);
	send_message_through_server(destid, msg);

	return 1;
}

int logoff(char **options)
{	
	send_logout();
	return 1;
}

int quit(char **options)
{
	return 0;
}

void socket_init()
{
	struct sockaddr_in addr;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&addr, sizeof(addr));

	addr.sin_family = AF_INET;
	addr.sin_port = htons(DEFAULT_PORT);
	addr.sin_addr.s_addr = 0;;
	if (bind(sockfd,(struct sockaddr*)&addr, sizeof(addr))
		== -1)
		perror("bind");		
	max_fd = sockfd;
}

static void timer(int s)
{
	if(state == ST_KEEPALIVE)
	{
		state = ST_LOGOUT;
	}
	else if(state == ST_RUNNING)
	{
		send_keep_alive();
	}
}

void init()
{
	struct itimerval val;
	struct sigaction newact;
	
	socket_init();
	friends_list_init();    
	newact.sa_handler = timer;
	sigemptyset(&newact.sa_mask);
	newact.sa_flags = 0;
	if (sigaction(SIGALRM, &newact, NULL) == -1) 
		perror("sigaction\n");
	
	val.it_interval.tv_sec  =  15;
	val.it_interval.tv_usec = 0;
	val.it_value = val.it_interval;
	if(setitimer(ITIMER_REAL,&val,NULL) < 0)
		perror("setitimer");
	
	
}

int send2server(const char* buf,int len)
{
    struct sockaddr_in addr;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(8000);
	addr.sin_addr.s_addr = inet_addr(server_ip);
	return sendto(sockfd,buf,len,0,(const struct sockaddr *)&addr,sizeof(addr));
}

int send2p(unsigned long id,const char* buf,int len)
{
    struct sockaddr_in addr;
	int i;
	addr.sin_family = AF_INET;	
	if(friends_list_query_ip(id) != UNINIT)	
	    addr.sin_addr.s_addr = friends_list_query_ip(id);
	else
	    return 0;
	addr.sin_port = htons(friends_list_query_port(id));	
	return sendto(sockfd,buf,len,0,(const struct sockaddr *)&addr,sizeof(addr));
}
void clean_up()
{
	printf("cleaning up...\n");
	close(sockfd);
}


int dispatcher()
{
	unsigned char buf[0x400];
	unsigned char message[0x400];
	unsigned long peerid;
	int len = sizeof(buf);    
	
	len = recvfrom(sockfd,buf,len,0,NULL,NULL);
	
	switch (buf[4]) {
	case MTYPE_LOGIN:		
		recv_ack_login(buf, len);
		send_request_friends_list();				
		break;
    case MTYPE_KEEP_ALIVE:
        recv_ack_keep_alive(buf,len);
        break;
    case MTYPE_USER_HEAD_PIC:
        recv_ack_user_head_pic(buf,len);
        break;
    case MTYPE_FRIENDS:
	recv_ack_friends_list(buf, len);		
	friends_list_print();
	break;
    case MTYPE_SEND_MESSAGE_THROUGH_SERVER:
        recv_ack_user_send_message_through_server(buf,len);
        break;
    case MTYPE_RECV_MESSAGE_THROUGH_SERVER:
        recv_message_through_server(&peerid,message,sizeof(message),buf,len);
        printf("The message from %u:\n%s\n",peerid,message);
        break;

	default:
		if(recv_message_from_peer(&peerid,message,sizeof(message),buf,len) <= 0)
		{
		    printf("unknown packet\n");
		}
		else
		    printf("message from %u:\n%s\n",peerid,message);
	}		
					
	return 1;
}

int Process_User_Input()
{
	char *tok;
	struct cmd_type *cmdptr;
	char *options[OPTION_MAX];
	int i;

	fgets((char *)buf, LINE_MAX, stdin);
	printf("user input: %s", buf);

	tok = strtok(buf, " ");

	cmdptr = &cmds[0];

	while (cmdptr->cmd_name) {
		if (strstr(tok, cmdptr->cmd_name)) {
			i = 0;

			while (options[i] = strtok(NULL, " "))
				++i;

			if (i < cmdptr->noption) {
				printf("Error number of options.\n");
				if (cmdptr->helper)
					(cmdptr->helper)();

				break;
			}

			return cmdptr->cmd_func(options);
		}
		++cmdptr;
	}

	return 1;
}


int message_loop() 
{
	int nfound;
    for (;;) {
		
		fprintf(stderr,"> ");
		FD_ZERO(&readfds);
		FD_SET(sockfd, &readfds);
		FD_SET(0, &readfds);

		/* select(listening_socket and STDIN) */
		if ((nfound = select(max_fd + 1, &readfds, NULL, NULL, NULL)) == -1) {
			if (errno == EINTR) 
				continue;

			perror("select");
			exit(1);
	        }		


		if (FD_ISSET(0, &readfds))
			if (!Process_User_Input())
			{
				break;
		        }
		if (FD_ISSET(sockfd, &readfds))
			if (!dispatcher())
				break;
	}

}
int main() 
{

	init();

	message_loop();

	clean_up();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -