📄 server.c~
字号:
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>#include <fcntl.h>//#define errexit(code,str) {fprintf(stderr,"%s: %s\n",(str),strerror(code)); exit(1);}#define PORT 8888#define MAXSIZE 1024#define BLOCK 8//用户信息数据结构typedef struct userinfo{ char id[15]; char psw[15]; char ip[15];}User;User users[BLOCK];//参数结构struct ARG{ int client_fd; struct sockaddr_in remote_addr; };int sockfd,recvbytes; //设置监听管道 ,接收字节数int client_fds[8];struct sockaddr_in my_addr; // 本机地址信息 //struct sockaddr_in remote_addr; //客户端地址信息 int sin_size;int linknum=-1,loginum=-1;FILE *fp;//建立服务器端socket接口void SetSocket(){ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Socket Create failed\n");
exit(1);
} int opt = SO_REUSEADDR; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(PORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("Bind Error!\n");
exit(1);
}}//启动服务void LanuchServer(){ if(listen(sockfd,BLOCK)==-1)
{
perror("Listen Error!\n");
exit(1);
} printf("Server has been setup!..............................\n");}//获取登录用户验证信息void GetUserInfo(char* info,int client_fd){ if((recvbytes=recv(client_fd,info,15,0))==-1) { perror("Receive from client failed!\n"); close(client_fd); close(sockfd); exit(1); } info[recvbytes]='\0'; printf("%s\n",info);}//验证用户int CheckOnUser(User user){ char id[15];
char psw[15]; do { fscanf(fp,"%s",id); if(strncmp(user.id,id,strlen(id))==0) { fscanf(fp,"%s",psw); if(strncmp(user.psw,psw,strlen(psw))==0) { rewind(fp); return 1; } } }while(fgetc(fp)!=EOF); rewind(fp); return 0;}//向客户端发送信息void SendMsg(const char* msg,int client_fd){ if(send(client_fd,msg,strlen(msg),0)==-1) { perror("Send Msg Error!\n"); close(client_fd); exit(1); }}//向新登录客户端发送在线用户列表int SendUserList(int clientfd){ if(loginum>0) { int i; for(i=0;i<loginum;i++) { int len; len=send(clientfd,users[i].id,strlen(users[i].id),0); if(len==-1)//if(send(clientfd,users[i].id,strlen(users[i].id),0)==-1) { perror("Send id error"); exit(1); }else if(len !=strlen(users[i].id)) { perror("Send msg_id has bug"); } printf("send user'id %s, %d chars\n",users[i].id,len); sleep(2); len=send(client_fds[loginum],users[i].ip,strlen(users[i].ip),0); if(len==-1)//if(send(client_fds[loginum],users[i].ip,strlen(users[i].ip),0)==-1) { perror("Send ip error"); exit(1); }else if(len!=strlen(users[i].ip)) { perror("Send msg_ip has bug"); } printf("send user'ip %s, %d chars\n",users[i].ip,len); sleep(2); } printf("to end userlist\n"); if(send(clientfd,"end",3,0)==-1) { perror("Send error"); exit(1); } return 1; } else { if(send(clientfd,"one",4,0)==-1) { perror("Send error"); exit(1); } } return 0;}//向已登录用户发送新用户登录的消息void AlterUsers(){ int i; if(loginum>0) { for(i=0;i<loginum;i++) { if(send(client_fds[i],users[loginum].id,strlen(users[loginum].id),0)==-1) { perror("Send new id error"); exit(1); } sleep(1); if(send(client_fds[i],users[loginum].ip,strlen(users[loginum].ip),0)==-1) { perror("Send ip error"); exit(1); } sleep(1); } }}void* start_routine1(void* arg){ int isOk=0; char info[15]; User user; struct ARG *argv=(struct ARG*)arg; if(linknum>=loginum) { while(!isOk) { GetUserInfo(info,argv->client_fd); if(strncmp(info,"quit",4)==0) { linknum--; break; } else { strcpy(user.id,info); GetUserInfo(user.psw,argv->client_fd); if(!CheckOnUser(user)) { SendMsg("Check Error",argv->client_fd); continue; } isOk=1; SendMsg("ok",argv->client_fd); loginum++; strncpy(users[loginum].id,user.id,strlen(user.id)+1); strcpy(users[loginum].ip,inet_ntoa(argv->remote_addr.sin_addr));//保存该客户端的ip client_fds[loginum]=argv->client_fd; sleep(1); if(SendUserList(argv->client_fd)) { sleep(3); AlterUsers(); } } } } //close(argv->client_fd); free(argv); rewind(fp); pthread_exit(0);}int main(){ pthread_t thread; int clientfd; struct sockaddr_in remote_addr; struct ARG *arg;
if((fp=fopen("users.txt","r"))==NULL)
{
perror("Cann't open the file!\n");
exit(1);
} SetSocket(); LanuchServer(); sin_size=sizeof(struct sockaddr_in); while(1) { if((clientfd=accept(sockfd,(struct sockaddr*)&remote_addr,&sin_size))==-1) { perror("Accept"); continue; } printf("Received a connection from %s\n",inet_ntoa(remote_addr.sin_addr)); linknum++; SendMsg("connect ok",clientfd); arg = (struct ARG*)malloc(sizeof(struct ARG)); arg->client_fd = clientfd; memcpy((void *)&arg->remote_addr, &remote_addr, sizeof(remote_addr)); if(pthread_create(&thread, NULL, start_routine1, (void*)arg)) { perror("pthread_creat() error"); exit(1); } } /* if(pthread_join(thread,NULL)) { exit(1); }*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -