/*
* 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 (); // find a user
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; // Save the information to be sent to the recipient
Char buf [1024];
Memset (buf, 0, 10, 24 );
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;
}