/*
* chat_server.h
*
* Created on: 2012-4-19
* Author: root
*/
#ifndef CHAT_SERVER_H_
#define CHAT_SERVER_H_
#include <iostream>
#include <string>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <fstream>
#include <time.h>
using namespace std;
#include <map>
#include <vector>
#define PORT 6000
typedef struct client_chat
{
char current_name[20];
char group[4];
char name[20];
char msg[200];
}ChatInfo;
struct Logic
{
char filename[50];
char time[20];
char str[50];
};
class chat_server
{
private:
int serverfd;
static map<int,string> ClientInfo;
pthread_mutex_t mutex;
public:
chat_server():serverfd(0){pthread_mutex_init(&mutex, NULL);
}
~chat_server(){close(serverfd);pthread_mutex_destroy(&mutex);}
int NetInit();
int find_user();
int find(string& name);
static void* recv_msg(void* temp);
void Accept();
void set_log(char* str);
};
struct ARG
{
int fd;
chat_server* pthis;
};
#endif /* CHAT_SERVER_H_ */
/*
* chat_server.cpp
*
* Created on: 2012-4-19
* Author: root
*/
#include "chat_server.h"
map<int,string> chat_server::ClientInfo;
void chat_server::set_log(char* str)
{
char name[10] = "error.log";
ofstream os(name,ios_base::out | ios_base::binary);
Logic log;
memcpy(&log.filename,name,strlen(name)+1);
time_t cur_time = time(NULL);
char* time = NULL ;
time = ctime(&cur_time);
memcpy(&log.time,time,strlen(time)+1);
memcpy(&log.str,str,strlen(str)+1);
os.write(reinterpret_cast<char*>(&log),sizeof(log));
os.close();
}
int chat_server::NetInit()
{
serverfd = socket(PF_INET,SOCK_STREAM,0);
if(serverfd<0)
{
cout << "Network busy!!!" << endl;
return -1;
}
struct sockaddr_in sock_ss;
sock_ss.sin_family = PF_INET;
sock_ss.sin_port = htons(PORT);
sock_ss.sin_addr.s_addr = htonl(0);
socklen_t len = sizeof(sock_ss);
// int bReuseaddr = 1;
//setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, ( const int* )&bReuseaddr, sizeof(int));
if( bind(serverfd,(struct sockaddr*)&sock_ss,len) < 0)
{
char str[20] = "listen failed";
set_log(str);
exit(-1);
}
if( listen(serverfd,10) < 0 )
{
cout << " failed" << endl;
}
cout << "listen start..." << endl;
char* s = "listen start";
set_log(s);
return serverfd;
}
int chat_server::find_user()
{
int i = 0;
map<int,string>::iterator iter = ClientInfo.begin();//查找用户
while(iter != ClientInfo.end())
{
cout << iter->first << "----->" << iter->second << endl;
i++;
iter++;
}
cout << "current zai xian ke hu: " << i << endl;
return 0;
}
int chat_server::find(string& name)
{
map<int,string>::iterator iter = ClientInfo.begin();
int tmpFd;
for(; iter != ClientInfo.end(); iter++)
{
string str = iter->second;
if(0 == str.compare(name))
{
cout<<"is find!!!"<<endl;
tmpFd = iter->first;
return tmpFd;
}
}
return -1;
}
void* chat_server::recv_msg(void* temp)
{
ARG* arg = (ARG*)temp;
chat_server* pthis = arg->pthis;
int sockfd = arg->fd;
while(1)
{
ChatInfo CInfo;//保存将要发送给对方的信息
char buf[1024];
memset(buf,0,1024);
int Ret = read(sockfd,buf,sizeof(buf));
map<int,string>::iterator iter;
if(Ret <= 0)
{
cout << "read anouise" << endl;
iter = ClientInfo.find(sockfd);
if(iter != ClientInfo.end())
{
ClientInfo.erase(sockfd);
}
close(sockfd);
pthread_exit(0);
}
char* pbuf = buf;
memcpy(&CInfo.current_name,pbuf,sizeof(CInfo.current_name));
pbuf += sizeof(CInfo.current_name);
memcpy(&CInfo.group,pbuf,sizeof(CInfo.group));
pbuf += sizeof(CInfo.group);
memcpy(&CInfo.name,pbuf,sizeof(CInfo.name));
pbuf += sizeof(CInfo.name);
memcpy(&CInfo.msg,pbuf,sizeof(CInfo.msg));
pthread_mutex_lock(&(pthis->mutex));
ClientInfo.insert(pair<int,string>(sockfd,CInfo.current_name));
pthread_mutex_unlock(&(pthis->mutex));
if(!strcmp(CInfo.group,"y"))
{
iter = ClientInfo.begin();
while(iter != ClientInfo.end())
{
memcpy(&CInfo.current_name,(iter->second).c_str(),sizeof(CInfo.current_name));
int Ret = write(iter->first,&CInfo,sizeof(CInfo));
iter++;
}
}
string tempname = CInfo.name;
int tmpFd = pthis->find(tempname);
if(tmpFd < 0)
{
ChatInfo nolog;
strcpy(nolog.current_name , CInfo.current_name);
strcpy(nolog.name , CInfo.name);
strcpy(nolog.msg ,"no login");
write(sockfd,&nolog,sizeof(nolog));
}else
{
ChatInfo logclient;
strcpy(logclient.current_name , CInfo.name);
strcpy(logclient.name , CInfo.current_name);
strcpy(logclient.msg ,CInfo.msg);
write(tmpFd,&logclient,sizeof(logclient));
}
}
return NULL;
}
void chat_server::Accept()
{
sockaddr_in from_addr;
while(1)
{
this->find_user();
socklen_t len = sizeof(from_addr);
int fd = accept(serverfd,(struct sockaddr*)&from_addr,&len);
if(fd < 0)
{
continue;
}
ARG* arg = new ARG();
arg->fd = fd;
arg->pthis = this;
pthread_t recv_pid = -1;
pthread_create(&recv_pid,NULL,recv_msg,(void*)arg);
}
}
/*
* chat_server_main.cpp
*
* Created on: 2012-4-19
* Author: root
*/
#include "chat_server.h"
int main(int argc,char** argv)
{
chat_server cs;
cs.NetInit();
cs.Accept();
return 0;
}