服务器与客户端简单通信 ——server

  • 作者:新网
  • 来源:新网
  • 2018-02-27 11:59:06

#define SERV_PORT 9000 #define BUFF_SIZE 1024 struct user { int socketfd; char name[20]; char toName[20];

#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

t017b23f94e06d395a2.jpg
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 ("create pthread error!n");
return -1;
}
pthread_detach(tid); // 线程分离
}

pthread_mutex_destroy(&mutex);

return 0;
}

  • 相关专题

免责声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,也不承认相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,请发送邮件至:operations@xinnet.com进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。

免费咨询获取折扣