#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include "wlock.c"
#define PORT 4321
#define BUFFER_SIZE 1024
#define MAX_QUE_CONN_NM 5
#define USERNAME_LEN 512
#define PASSWORD_LEN 512
#define DEST_FILE_NAME "userinfo.txt"
#define SEPARATOR ":"
#define USER_NUM 20
#define MAX_SOCK_FD FD_SETSIZE
struct sockaddr_in server_sockaddr, client_sockaddr,udp_sockaddr;
int sin_size=2, recvbytes,sendbytes;
int sockfd, client_fd;
int client[USER_NUM];
char bufr[BUFFER_SIZE];
char bufs[BUFFER_SIZE];
char buffer[BUFFER_SIZE];
char n_t[50];
fd_set inset;
fd_set tmp_inset;
pthread_t thread[USER_NUM];
int arg,res,k=0;
int cli_port=2000;
struct node
{
char name[50]; //用户名存放数组
struct sockaddr_in client_addr;//用户地址存放
int fd;
struct node *next; //指针
};
struct node *head;
struct node *create_list()
{
struct node *head;
head = (struct node *)malloc(sizeof(struct node));
head->next = NULL;
printf("creat the list!\n");
return head;
}
void insert_list(struct node *head, char *name, struct sockaddr_in *client_addr,int *fd)
{
struct node *new;
new = (struct node *)malloc(sizeof(struct node));
strcpy(new->name,name);
new->client_addr = *client_addr;
new->fd=*fd;
printf("insert name:%s fd:%d\n",new->name,new->fd);
new->next = head->next;
head->next = new;
return ;
}
void print_list(struct node *head)
{
struct node *p;
printf ("print the list:\n");
p = head;
if(head != NULL) //只要不是空链表,就输出链表中所有节点
{
while(p != NULL)
{
printf ("name:%s fd=%d\n",p->name, p->fd);
p = p->next; //移到下一个节点
}
}
}
void send_name(struct node *head,int fd)
{ int i=1;
struct node *p;
p = head;
memset(bufs, 0, sizeof(bufs));
strcat(bufs,"online user:\n");
if(head != NULL) //只要不是空链表,就输出链表中所有节点
{
while(p != NULL)
{
strcat(bufs,p->name);
if(i!=1) strcat(bufs,"\n");
i++;
p = p->next; //移到下一个节点
}
}
if ((sendbytes = send(fd, bufs,BUFFER_SIZE, 0)) == -1)
{
perror("send");
exit(1);
}
}
void broadcast(struct node *head,int cli)
{
struct node *p;
p = head;
if(head != NULL) //只要不是空链表,就输出链表中所有节点
{
while(p != NULL)
{
memset(bufs, 0, sizeof(bufs));
strcpy(bufs,"Client ");
strcat(bufs,p->name);
strcat(bufs," has left\n");
if ((sendbytes = send(p->fd, bufs,BUFFER_SIZE, 0)) == -1)
{
perror("send");
exit(1);
}
p = p->next; //移到下一个节点
}
}
}
void delete_list(struct node *head,int *fd)
{
struct node *p = head->next;
struct node *q = head;
while (p!= NULL)
{
if (p->fd ==*fd)
{
printf ("delete name:%s fd=%d\n",p->name, p->fd);
q->next = p->next;
p->next = NULL;
free(p);
break;
}
p = p->next;
q = q->next;
}
return ;
}
void name_addr(struct node *head,char *name,int cli)
{
struct node *p = head->next;
struct node *q = head;
while (p!= NULL)
{
if (0==strcmp(p->name,name))
{
printf ("find name:%s fd=%d\n",p->name, p->fd);
////////////////////// send addr stucture
ser_s(cli,"DEST_ADDR") ;
if ((sendbytes = send(cli,&p->client_addr,sizeof(struct sockaddr_in), 0)) == -1)
{
perror("send");
exit(1);
}
return ;
}
p = p->next;
q = q->next;
}
ser_s(cli,"该用户不在线!\n") ;
return ;
}
/////////////////////////////////////////////////
int ser_link_start()
{
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
printf("Socket id = %d\n",sockfd);
/*赋初值*/
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT); /*改数据存储优先顺序*/
server_sockaddr.sin_addr.s_addr = INADDR_ANY; /*表示任何地址*/
bzero(&(server_sockaddr.sin_zero), 8); /*置字符串前n个字节为零的函数*/
int i = 1;
if( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i))<0 )
{ perror("setsockopt failed");
exit(EXIT_FAILURE);
}
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr))== -1)
{
perror("bind"); /*perror(“。。。。”);用于屏幕显示出错原因*/
exit(1);
}
printf("Bind success!\n");
if (listen(sockfd, MAX_QUE_CONN_NM) == -1)
{
perror("listen");
exit(1);
}
printf("Listening....\n");
}
int ser_link_end()
{
close(client_fd);
close(sockfd);
exit(0);
}
int ser_r(int cli) //服务器接收
{
memset(bufr , 0, sizeof(bufr));
if ((recvbytes = recv(cli, bufr, BUFFER_SIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
printf("recv from client_fd is %d:%s",cli,bufr);
}
int ser_s(int cli,char ch[])
{
memset(bufs, 0, sizeof(bufs));
strcpy(bufs,ch);
if ((sendbytes = send(cli, bufs,BUFFER_SIZE, 0)) == -1)
{
perror("send");
exit(1);
}
//printf("server send %d byte: %s\n",strlen(bufs), bufs);
}
int ser_adu(int cli)
{FILE *stream;
char buf[USERNAME_LEN+PASSWORD_LEN];
char username[USERNAME_LEN],password[PASSWORD_LEN],separator[]={":"};
char *u_cmp;
int fd;
fd=cli;
memset(buf, 0, sizeof(buf));
memset(username, 0, sizeof(username));
memset(password, 0, sizeof(password));
ser_s(fd,"欢迎注册用户!\n"); //s1
stream=fopen(DEST_FILE_NAME,"a+");
if(!stream) {printf("open file error!\n");}
wlock(fd);///////
ser_s(fd,"请输入您要注册到用户名(注意输入状态为中文还是英文):\n"); //s2
//scanf("%s",&username);
ser_r(fd); //r1
strncpy(username,bufr,strlen(bufr)-1); //输入有回车 \n
fseek(stream,0,SEEK_SET);
while(fgets(buf,USERNAME_LEN+PASSWORD_LEN,stream)!=NULL)
{u_cmp=strtok(buf,SEPARATOR);
if(0==strcmp(username,u_cmp)) {ser_s(fd,"用户名已存在!\n"); return -1;} //s special
}
fseek(stream,0,SEEK_END);
ser_s(fd,"请输入您到密码:\n"); //s3
// scanf("%s",&password);
ser_r(fd); //r2
strncpy(password,bufr,strlen(bufr)-1); //有回车
memset(buf, 0, sizeof(buf)); //使用数组前一定要先清空
strncpy(buf,username,strlen(username));
strcat(buf,separator);
strncat(buf,password,strlen(password));
strcat(buf,"\n");
fputs(buf,stream);
unlock(fd);////////
fclose(stream);
ser_s(fd,"用户注册成功!");//s4
return 0;
}
///////////////////////////////////////////////////
int ser_log(int cli)
{FILE *stream;
char buf[BUFFER_SIZE];
char username[USERNAME_LEN],password[PASSWORD_LEN];
char *u_cmp,*p_cmp,*t;
int fd,fd_dest,u;
char sel,ou_name[BUFFER_SIZE];
char temp[USERNAME_LEN];
fd=cli;
memset(buf, 0, sizeof(buf));
memset(username, 0, sizeof(username));
memset(password, 0, sizeof(password));
ser_s(fd,"欢迎登录!\n"); //s1
ser_s(fd,"请输入您的用户名:\n"); //s2
//scanf("%s",&username);
ser_r(fd); //r1
strncpy(username,bufr,strlen(bufr)-1); //输入有回车 \n
stream=fopen(DEST_FILE_NAME,"a+");
if(!stream) printf("open file error!\n");
fseek(stream,0,SEEK_SET);
while(fgets(buf,USERNAME_LEN+PASSWORD_LEN,stream)!=NULL)
{u_cmp=strtok(buf,SEPARATOR);
if(0==strcmp(username,u_cmp))
{
ser_s(fd,"请输入您到密码:\n"); //s3
ser_r(fd); //r2
strncpy(password,bufr,strlen(bufr)-1); //有回车
p_cmp=strtok(NULL,SEPARATOR);
strncpy(temp,p_cmp,(strlen(p_cmp)-1));
// printf("ceshi passwordlen=%d templen=%d cmp=%d\n",strlen(password),strlen(temp),strcmp(temp,password));
if(0==strcmp(temp,password) )
//之前