基于C++的局域网聊天系统服务器端源码

/*
 * 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值