#include "stdafx.h"
#include "winsock2.h"
#include "stdlib.h"
#include <map>
#include <string>
#include <iostream>
using namespace std;
#define PROTOPORT 5188
#define QLEN 6
void usage(_TCHAR *name)
{
fprintf(stderr, "usage: %s [port]\n", name);
}
DWORD WINAPI ThreadServ(LPVOID p);
struct Message
{
string from;
string to;
string text;
};
int no=0;
map<int,Message> log;
map<string, SOCKET> clients;
CRITICAL_SECTION CSlog;////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
SOCKET servsock, clisock;
struct sockaddr_in sa;
struct sockaddr_in cliaddr;
int len;
int err;
int servport = 5555;
WSADATA wsd;
printf("****************************************\n");
printf("* hell express highway *\n");
printf("****************************************\n");
InitializeCriticalSection(&CSlog);////////
if(argc > 2)
{
usage(argv[0]);
return -1;
}
if(argc == 2)
{
servport = _wtoi(argv[1]);
if(servport > 65535 || servport < 1)
{
usage(argv[0]);
return -2;
}
}
if(WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("WSAStartup() failed!\n");
return -3;
}
printf("Creating socket ...\n");
servsock = socket(AF_INET, SOCK_STREAM, 0);
if (servsock == INVALID_SOCKET)
{
fprintf(stderr, "socket() failed: %d\n", WSAGetLastError() );
return -4;
}
printf("[0K]\n");
memset(&sa, 0, sizeof(sa) );
sa.sin_family = AF_INET;
sa.sin_port = htons(servport);
sa.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
printf("Bind ...\n");
err = bind(servsock, (const sockaddr *)&sa, sizeof(sa));
if(err!=0)
{
fprintf(stderr, "bind() failed: %d\n", WSAGetLastError() );
return -5;
}
printf("[OK]\n");
printf("listen ...\n");
err = listen(servsock, 5);
if(err != 0)
{
fprintf(stderr, "listen() failed: %d\n", WSAGetLastError() );
return -6;
}
printf("[0k]\n");
while(1)
{
printf("wait request ...\n");
len = sizeof(cliaddr);
clisock = accept(servsock, (struct sockaddr *) &cliaddr, &len);
if(clisock == INVALID_SOCKET)
{
fprintf(stderr, "accept() failed: %d\n", WSAGetLastError());
closesocket(servsock);
return -7;
}
printf("accept client: %s:%d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port) );
CreateThread(NULL, 0, ThreadServ, (LPVOID)&clisock, 0, NULL);
}
closesocket(servsock);
WSACleanup();
return 0;
}
////////////////
DWORD WINAPI ThreadServ(LPVOID p)
{
char buff[256];
int last=0;
string name;
string tsend;
SOCKET clisock = *(SOCKET *)p;
printf("wait username..");
memset(buff, 0, sizeof(buff));
if(recv(clisock, buff, sizeof(buff), 0) == SOCKET_ERROR)
{
fprintf(stderr, " recv error !\n");
return -1;
}
printf("done\n");
printf("received: %s\n", buff);
name=buff; //预留重复昵称检测
clients.insert(map<string,SOCKET>::value_type(name,clisock));
sprintf_s(buff, "succeed");
send(clisock, buff, sizeof(buff), 0);
cout<<name<<" loged on";
while(1)
{
printf("wait message..\n");
memset(buff, 0, sizeof(buff));
if(recv(clisock, buff, sizeof(buff), 0) == SOCKET_ERROR)
{
fprintf(stderr, " recv error !\n");
return -1;
}
//>>>>>>>>>>>>>>>
if('&'==buff[0])
{
printf("buff[0] is &\n");
printf("recv:%s\n",buff);
char to[20];
char text[100];
int i,n;
for(i=1;buff[i]!=':';i++){to[i-1]=buff[i];}to[i-1]='\0';i++;
for(n=0;buff[i]!='\0';i++,n++){text[n]=buff[i];}text[n]='\0';
Message msg;
msg.from=name;
msg.to=to;
msg.text=text;
EnterCriticalSection(&CSlog);////
log.insert(map<int,Message>::value_type(no,msg));no++;
LeaveCriticalSection(&CSlog);////
cout<<msg.from<<"|"<<msg.to<<"|"<<msg.text;
}
else if(0==strcmp("@getchat",buff))
{
//printf("GOT IT\n");
map<int,Message>::iterator itor;
while(last!=no)
{
for(itor = log.find(last); itor != log.end(); itor++)
{
if("all" == itor->second.to||name == itor->second.to)
{
tsend=itor->second.from;
tsend+=" >> ";
tsend+=itor->second.to;
tsend+=" : ";
tsend+=itor->second.text;
tsend+="\n";
send(clisock, tsend.c_str(), tsend.length(), 0);
}
}
last=no;
}
}
else
{
Message msg;
msg.from=name;
msg.to="all";
msg.text=buff;
EnterCriticalSection(&CSlog);////
log.insert(map<int,Message>::value_type(no,msg));no++;
LeaveCriticalSection(&CSlog);////
cout<<msg.from<<"|"<<msg.to<<"|"<<msg.text;
}
}
return 0;
}