慕神4583458 的学生作业:
【图片】
server.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUF_SZ 1024
enum LOGIN_STATUS {
LOGIN_FAIL = 0,
LOGIN_SUCCESS = 1,
};
typedef struct message_thread_arg {
char *ip;
unsigned char status;
struct sockaddr_in *recv_addr;
} message_thread_arg_t;
int init_socket(char *ip, char *port) {
int socketfd;
socketfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr_in;
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(atoi(port));
addr_in.sin_addr.s_addr = inet_addr(ip);
int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in));
return socketfd;
}
void recv_data(int socketfd) {
int bytes;
char buf[1024];
struct sockaddr_in recv_addr;
socklen_t len = sizeof(struct sockaddr);
while(1) {
printf("wait data====\n");
memset(buf, 0, sizeof(buf));
bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len);
if (bytes == -1) {
perror("[ERROR] recvfrom():");
exit(EXIT_FAILURE);
}
printf("ip = %s port = %d\n", inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port));
printf("Recv size = %d buf = %s\n", bytes, buf);
if (strcmp(buf, "quit") == 0) break;
}
pthread_exit(NULL);
}
void *message_thread(void *arg) {
message_thread_arg_t *thread_arg = (message_thread_arg_t *)arg;
int new_socketfd = init_socket(thread_arg->ip, "0");
sendto(new_socketfd, &thread_arg->status, sizeof(thread_arg->status), 0, (struct sockaddr *)thread_arg->recv_addr, sizeof(*thread_arg->recv_addr));
recv_data(new_socketfd);
}
int user_login(char *ip, char *port) {
int socketfd = init_socket(ip, port);
int new_socketfd;
int bytes;
char buf[20];
struct sockaddr_in recv_addr;
socklen_t len = sizeof(struct sockaddr);
unsigned char status = 0;
pthread_t tid;
message_thread_arg_t thread_arg;
while(1) {
memset(buf, 0, sizeof(buf));
bytes = recvfrom(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&recv_addr, &len);
if (bytes == -1) {
perror("[ERROR] recvfrom():");
exit(EXIT_FAILURE);
}
status = strcmp(buf, "root") == 0 ? LOGIN_SUCCESS : LOGIN_FAIL;
if (status == LOGIN_SUCCESS) {
printf("login success\n");
thread_arg.ip = ip;
thread_arg.recv_addr = &recv_addr;
thread_arg.status = status;
tid = pthread_create(&tid, NULL, message_thread, (void *)&thread_arg);
pthread_detach(tid);
} else {
printf("login fail\n");
sendto(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, len);
}
}
return new_socketfd;
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, " %s ip port", argv[0]);
exit(EXIT_FAILURE);
}
int socketfd = user_login(argv[1], argv[2]);
return 0;
}
client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUF_SZ 1024
enum LOGIN_STATUS {
LOGIN_FAIL = 0,
LOGIN_SUCCESS = 1,
};
int init_socket(char *ip, char *port) {
int socketfd;
socketfd = socket(AF_INET, SOCK_DGRAM, 0);
// struct sockaddr_in addr_in;
// addr_in.sin_family = AF_INET;
// addr_in.sin_port = htons(atoi(port));
// addr_in.sin_addr.s_addr = inet_addr(ip);
// int ret = bind(socketfd, (struct sockaddr *)&addr_in, sizeof(addr_in));
return socketfd;
}
void send_data(int socketfd, struct sockaddr_in *paddr_in) {
int ret;
char buf[1024];
while(1) {
printf("root:>");
fflush(NULL);
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
ret = sendto(socketfd, buf, strlen(buf), 0, (struct sockaddr *)paddr_in, sizeof(*paddr_in));
if (ret == -1) {
perror("[ERROR] sendto():");
exit(EXIT_FAILURE);
}
if (strcmp(buf, "quit") == 0) {
exit(EXIT_SUCCESS);
}
}
}
void user_login(char *ip, char *port) {
int socketfd = init_socket(ip, port);
int bytes;
char buf[1024];
struct sockaddr_in send_addr;
send_addr.sin_family = AF_INET;
send_addr.sin_addr.s_addr = inet_addr(ip);
send_addr.sin_port = htons(atoi(port));
struct sockaddr_in recv_addr;
socklen_t len = sizeof(struct sockaddr);
short status = 0;
while(1) {
putchar('>');
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = '\0';
sendto(socketfd, buf, sizeof(buf), 0, (struct sockaddr *)&send_addr, sizeof(send_addr));
bytes = recvfrom(socketfd, &status, sizeof(status), 0, (struct sockaddr *)&recv_addr, &len);
if (bytes == -1) {
perror("[ERROR] recvfrom():");
exit(EXIT_FAILURE);
}
if (status == LOGIN_SUCCESS) break;
}
printf("break");
send_data(socketfd, &recv_addr);
}
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, " %s ip port", argv[0]);
exit(EXIT_FAILURE);
}
user_login(argv[1], argv[2]);
return 0;
}