📄 sk.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 + -