#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define serv_port 9000
#define buff_size 1024
struct user
{
int socketfd;
char name[20];
char toname[20];
int result; // 0 代表失败 1代表成功 2 代表别人给你发的信息 3代表没注册 4错误的指令
char msg[100];
int cmd; // 5 代表注册用户 10 // 代表发送信息
};
struct usermanage
{
int flag[20]; // 表明哪个空缺
struct user users[20];
};
pthread_mutex_t mutex;
struct usermanage umge;
void save_user(int socket_fd, struct user * userinfo)
{
pthread_mutex_lock(&mutex);
int i = 0;
for (i = 0; i < 20; i )
{
if (umge.flag[i] == 1)
{
continue;
}
umge.users[i].socketfd = socket_fd;
strcpy(umge.users[i].name, userinfo->name);
userinfo->result = 1;
umge.flag[i] = 1;
printf ("%s register success!n", umge.users[i].name);
break;
}
pthread_mutex_unlock(&mutex);
}
int server_request(int cfd)
{
int readsize, writesize;
int ret = 0;
int i;
struct user userinfo;
int toname_fd = -1;
int isregister = -1;
while (readsize = read(cfd, &userinfo, sizeof(userinfo)))
{
if (readsize == -1)
{
perror("read");
return -1;
}
if (userinfo.cmd == 5) // 注册用户
{
save_user(cfd, &userinfo); // 将用户信息进行保存
}
else if (userinfo.cmd == 10) // 发送信息
{
// 检测该用户是否注册
for (i = 0; i < 20; i )
{
if (umge.flag[i] == 1)
{
if (umge.users[i].socketfd == cfd)
{
if (strcmp(umge.users[i].name, userinfo.name) == 0)
{
isregister = 1;
}
}
}
}
if(isregister == 1)
{
// 寻找要发送的用户
for (i = 0; i < 20; i )
{
if (umge.flag[i] == 1)
{
// 找到了要发送的用户,将其socket保存起来
if (strcmp(umge.users[i].name, userinfo.toname) == 0)
{
toname_fd = umge.users[i].socketfd;
}
}
}
if(toname_fd != -1) // 没找到要发送的用户
{
userinfo.result = 2; // 找到用户将其返回状态标为1
writesize = write(toname_fd, &userinfo, sizeof(userinfo));
if (writesize == -1)
{
perror("write");
return -1;
}
printf ("%s send msg to %s : %sn", userinfo.name, userinfo.toname, userinfo.msg);
userinfo.result = 1; // 发送成功
}
}
else
{
userinfo.result = 3; // 没有注册
}
}
else
{
userinfo.result = 4; // 错误的指令
}
writesize = write(cfd, &userinfo, sizeof(userinfo));
if (writesize == -1)
{
perror("write");
return -1;
}
memset(userinfo.msg, 0, sizeof(userinfo.msg));
}
}
int main()
{
int listen_sockfd;
int ret;
struct sockaddr_in server_addr; // 服务器地址结构
struct sockaddr_in client_addr; // 客户端的地址
pthread_mutex_init(&mutex, null);
// 创建监听套接字
listen_sockfd = socket(af_inet, sock_stream, 0);
if (listen_sockfd == -1)
{
perror("create socket error");
return -1;
}
// 初始化服务器地址结构
bzero(&server_addr, sizeof(server_addr)); // 将地址结构变量清零
server_addr.sin_family = af_inet; // 选择ipv4地址
server_addr.sin_addr.s_addr = htonl(inaddr_any); // 监听本地任意ip地址
server_addr.sin_port = htons(serv_port); // 将本地端口号转化为网络端口号
// 绑定本地地址和端口号
ret = bind(listen_sockfd, (struct sockaddr *)&server_addr, sizeof (server_addr));
if (ret == -1)
{
perror ("bind error");
return -1;
}
// 监听套接字
ret = listen(listen_sockfd, 20);
if (ret == -1)
{
perror("listen error");
return -1;
}
while(1)
{
int clientfd;
socklen_t client_len = sizeof(client_addr);
clientfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &client_len);
if (clientfd == -1)
{
perror("accept error");
return -1;
}
pthread_t tid;
// 创建线程处理客户端请求
int ret = pthread_create(&tid, null, server_request, (void *)clientfd);
if (ret != 0)
{
printf ("cre