大禹123 的学生作业:
#include "server.h"
#define LOGIN_FAIL 0
#define LOGIN_SUCCESS 1
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int login_flag = 0;
int create_socket_and_bind(const char *ip, const char *port)
{
int sockfd;
struct sockaddr_in addr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
socklen_t addrlen = sizeof(struct sockaddr_in);
if(sockfd == -1)
{
perror("[ERROR] socket():");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
//端口字符---》整数---》网络字节序
addr.sin_port = htons(atoi(port)) ;
//ip字符---》网络字节序
addr.sin_addr.s_addr = inet_addr(ip);
if((bind(sockfd, (const struct sockaddr *)&addr, addrlen))==-1)
{
perror("[ERROR] bind():");
return -1;
}
return sockfd;
}
void *recive_data(void *arg)
{
int ret;
char buf[256] = {0};
struct sockaddr_in client_addr;
int newsockfd = *(int *)arg;
int addrlen = sizeof(struct sockaddr_in);
memset(&client_addr, 0, sizeof(struct sockaddr_in));
while(1)
{
memset(buf, 0, sizeof(buf));
if((recvfrom(newsockfd, (void *)buf, sizeof(buf), 0,(struct sockaddr *)&client_addr, &addrlen))==-1)
{
perror("[ERROR] recvfrom():");
pthread_exit(NULL);
}
print_client_info(&client_addr, buf);
if(strncmp(buf,"quit",4) == 0)
{
close(newsockfd);
pthread_exit(NULL);
}
}
}
void msg_handle(const char *ip, const char *port, socklen_t addrlen)
{
char buf[256] = {0};
struct sockaddr_in client_addr;
int ret;
pthread_t tid;
int newsockfd;
int sockfd = create_socket_and_bind(ip, port);
if(sockfd == -1)
{
exit(EXIT_FAILURE);
}
memset(&client_addr, 0, sizeof(struct sockaddr_in));
while(1)
{
if((recvfrom(sockfd, (void *)buf, sizeof(buf), 0,(struct sockaddr *)&client_addr, &addrlen))==-1)
{
perror("[ERROR] recvfrom():");
exit(EXIT_FAILURE);
}
login_flag = (strncmp(buf,"root",4) == 0) ? LOGIN_SUCCESS : LOGIN_FAIL;
//如果登录成功了,那么创建子进程处理消息发送
if(login_flag == LOGIN_SUCCESS)
{
newsockfd = create_socket_and_bind(ip, "0");
if(newsockfd == -1)
{
exit(EXIT_FAILURE);
}
ret = sendto(newsockfd, (const void *)&login_flag, sizeof(login_flag), 0, (const struct sockaddr*)&client_addr, addrlen);
if(ret == -1)
{
perror("[ERROR] sendto():");
pthread_exit(NULL);
}
ret = pthread_create(&tid, NULL, recive_data, (void *)&newsockfd);
if(ret!=0)
{
fprintf(stderr,"[ERROR] pthread_create(): < %s >", strerror(ret));
exit(EXIT_FAILURE);
}
pthread_detach(tid);
}else
{
//如果失败了,那么告诉客户端登录失败
sendto(sockfd, (const void *)&login_flag, sizeof(login_flag), 0, (const struct sockaddr*)&client_addr, addrlen);
}
}
return ;
}
void print_client_info(struct sockaddr_in *client_addr, char *buf)
{
pthread_mutex_lock(&mutex);
printf("\n==========================\n");
printf("client ip: %s\n", inet_ntoa(client_addr->sin_addr));
printf("client port: %d\n", ntohs(client_addr->sin_port));
printf("client buf: %s\n", buf);
pthread_mutex_unlock(&mutex);
}
//server ip port
int main(int argc, char const *argv[])
{
int new_sockfd;
socklen_t addrlen = sizeof(struct sockaddr_in);
if(argc!=3)
{
fprintf(stderr,"Usage: %s ip port\n", argv[0]);
exit(EXIT_FAILURE);
}
msg_handle(argv[1], argv[2], addrlen);
return 0;
}