别摸我的键盘 的学生作业:
#include
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FILE_SZ 64
#define LOGIN_FAIL_STATE 0
#define LOGIN_SUCCESS_STATE 1
#define DEBUG 0
void printf_data_info(struct sockaddr_in * addr_in, char *buf){
printf("=======================================================\n");
printf("host is %s\n", inet_ntoa(addr_in -> sin_addr));
printf("port is %d\n", ntohs(addr_in -> sin_port));
printf("buf content is %s\n", buf);
printf("=======================================================\n");
}
int socket_init(const char *ip, const char *port){
int socket_fd;
struct sockaddr_in addr_in;
int ret;
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(socket_fd == -1){
perror("[ERROR] socket()");
exit(EXIT_FAILURE);
}
memset(&addr_in, 0, sizeof(addr_in));
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(atoi(port));
addr_in.sin_addr.s_addr = inet_addr(ip);
ret = bind(socket_fd, (const struct sockaddr*)&addr_in, sizeof(addr_in));
if(ret == -1){
perror("[ERROR] bind()");
exit(EXIT_FAILURE);
}
return socket_fd;
}
typedef struct{
char *ip;
unsigned char login_state;
struct sockaddr_in *addr_in;
}thread_info_t;
void * do_thread(void *arg){
int socket_new_fd;
char buf[FILE_SZ];
ssize_t sz;
thread_info_t *tinfo_t = (thread_info_t *)arg;
char *ip = tinfo_t -> ip;
unsigned char login_state = tinfo_t -> login_state;
struct sockaddr_in *addr_in = tinfo_t -> addr_in;
#if DEBUG
printf("ip is %s\n", ip);
printf("login_state is %d\n", login_state);
printf("host is %s\n", inet_ntoa(addr_in ->sin_addr));
printf("port is %d\n", ntohs(addr_in -> sin_port));
#endif
//注意:这里的长度必须是 sizeof(struct sockaddr_in) 否则会存在问题
int len = sizeof(struct sockaddr_in);
socket_new_fd = socket_init(ip, "0");
sendto(socket_new_fd, &login_state, sizeof(login_state), 0, (struct sockaddr *) addr_in, len);
while(1){
memset(buf, 0, sizeof(buf));
sz = recvfrom(socket_new_fd, buf, sizeof(buf), 0, (struct sockaddr *) addr_in, &len);
if(sz == -1){
perror("[ERROR] recvfrom()");
exit(EXIT_FAILURE);
}
printf_data_info(addr_in, buf);
if(strncmp(buf, "quit", 4) == 0){
break;
}
}
close(socket_new_fd);
pthread_exit(NULL);
}
void user_login(char *ip, char *port){
int socket_fd;
struct sockaddr_in addr_in;
char buf[FILE_SZ];
int len = sizeof(addr_in);
ssize_t sz;
unsigned char login_state = LOGIN_FAIL_STATE;
pthread_t pid;
thread_info_t tinfo_t;
socket_fd = socket_init(ip, port);
while(1){
memset(buf, 0, sizeof(buf));
sz = recvfrom(socket_fd, buf, sizeof(buf), 0, (struct sockaddr *) &addr_in, &len);
if(sz == -1){
perror("[ERROR] recvfrom()");
exit(EXIT_FAILURE);
}
printf("pwd is %s\n", buf);
login_state = (strncmp(buf, "root", 4) == 0 ? LOGIN_SUCCESS_STATE : LOGIN_FAIL_STATE);
if(login_state == LOGIN_SUCCESS_STATE){
printf("login success!\n");
tinfo_t.ip = ip;
tinfo_t.login_state = login_state;
tinfo_t.addr_in = &addr_in;
#if DEBUG
printf("ip is %s\n", tinfo_t.ip);
printf("login_state is %d\n", tinfo_t.login_state);
printf("host is %s\n", inet_ntoa(tinfo_t.addr_in ->sin_addr));
printf("port is %d\n", ntohs(tinfo_t.addr_in -> sin_port));
#endif
pthread_create(&pid, NULL, do_thread, (void *)&tinfo_t);
}else{
sendto(socket_fd, &login_state, sizeof(login_state), 0, (struct sockaddr *) &addr_in, len);
}
pthread_detach(pid);
}
}
int main(int argc, const char *argv[])
{
if(argc != 3){
fprintf(stderr, "[ERROR] %s \n", argv[0]);
exit(EXIT_FAILURE);
}
user_login((char *)argv[1], (char *)argv[2]);
return 0;
}