#include <iostream>
#include <stdio.h>
#include <string>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define DEFAULT_PORT "8800" // 端口
#define MAX_REQUEST 1024 // 接收数据的缓存大小
#define SEND_BUFFER_SIZE 4096 // 发送数据的缓存大小
#define CAPACITY 1024
class ClientInfo
{
public:
string id;
SOCKET connectionSocket;
bool ifUsed;
public:
ClientInfo()
{
ifUsed = false;
}
};
ClientInfo Client[CAPACITY];
SOCKADDR_IN sockaddr;
int len=sizeof(SOCKADDR);
string TimeFormat(SYSTEMTIME serverTime)
{
string time = "";
char* buffer = new char(10);
itoa(serverTime.wYear,buffer,10);
time = time + buffer + "-";
itoa(serverTime.wMonth,buffer,10);
time = time + buffer + "-";
itoa(serverTime.wDay,buffer,10);
time = time + buffer + " ";
itoa(serverTime.wHour,buffer,10);
time = time + buffer + ":";
itoa(serverTime.wMinute,buffer,10);
time = time + buffer + ":";
itoa(serverTime.wSecond,buffer,10);
time = time + buffer;
return time;
}
int U2A(const wchar_t* szU,char* szA,size_t cnt)
{
return WideCharToMultiByte (CP_ACP, 0, szU, -1, szA, cnt, NULL, NULL) ;
}
int A2U(const char* szA,wchar_t* szU,size_t cnt)
{
return MultiByteToWideChar (CP_ACP, 0, szA, -1, szU, cnt) ;
}
string U2A(const wchar_t* szU)
{
int nRetCode=U2A(szU,0,0);
if(0==nRetCode)
return std::string();
std::string str(nRetCode-1,'\0');
U2A(szU,(char*)(str.c_str()),nRetCode);
return str;
}
wstring A2U(const char* szA)
{
int nRetCode=A2U(szA,0,0);
if(0==nRetCode)
return std::wstring();
std::wstring str(nRetCode-1,'\0');
A2U(szA,(wchar_t*)(str.c_str()),nRetCode);
return str;
}
string GetNames()
{
DWORD dwComputerNameLen = MAX_COMPUTERNAME_LENGTH+1;
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
GetComputerName(szComputerName,&dwComputerNameLen);
string computerName = U2A(szComputerName);
return computerName;
}
DWORD WINAPI CommunicationThread(LPVOID lpParameter)
{
DWORD Tid = GetCurrentThreadId();
ClientInfo* pData = (ClientInfo*)lpParameter;
// 获得参数sokcet
SOCKET socket = pData->connectionSocket;
// 为接收数据分配空间
LPSTR request = (LPSTR )HeapAlloc(GetProcessHeap(),0, MAX_REQUEST);
int tmpResult;
int bytesSent; // 用于保存send的返回值,实际发送的数据的大小
while(1)
{
// 接收数据
tmpResult = recv(socket, request, MAX_REQUEST, 0);
if (tmpResult == 0 || tmpResult == SOCKET_ERROR) // 接收数据失败,关闭连接
{
cout<<"Connection closing..."<<endl;
//HeapFree(GetProcessHeap(), 0 ,request);
closesocket(socket);
return 0;
}
else if (tmpResult > 0) // 接收数据成功
{
// 显示接收到的数据
printf("\tCommunicationThread(%d)\tBytes received: %d\n", Tid, tmpResult);
printf("\tCommunicationThread(%d)\trequest string is (%s)\n",Tid, request);
string rtnData = "";
string message = request;
if(strnicmp(message.c_str(),"T",1) == 0){
SYSTEMTIME serverTime;
GetLocalTime(&serverTime);
rtnData = TimeFormat(serverTime) + "#";
}
else if(strnicmp(message.c_str(),"N",1) == 0){
rtnData = GetNames() + "#";
}
else if(strnicmp(message.c_str(),"L",1) == 0 ){
for(int i=0; i<CAPACITY; i++)
{
if(Client[i].ifUsed == true)
{
getpeername(Client[i].connectionSocket,(SOCKADDR*)&sockaddr,&len);// 获取客户端 IP地址
char* port = new char(10);
itoa(sockaddr.sin_port,port,10);
rtnData = rtnData + " ID : " + Client[i].id + " IP : " + inet_ntoa(sockaddr.sin_addr) + " Port : "+ port + "#";
}
}
}
else if(strnicmp(message.c_str(),"S",1) == 0 ){
int i;
string destinationID = "";
string sendData = "";
for(i=6; i<message.size(); i++)
{
if(message.at(i) != '>')
destinationID = destinationID + message.at(i);
else
break;
}
for(int j=i+2; j<message.size(); j++)
{
if(message.at(j) != '>')
sendData = sendData + message.at(j);
else
break;
}
SOCKET tmpSocket;
for(int position=0; position<CAPACITY; position++)
{
if(Client[position].id == destinationID)
tmpSocket = Client[position].connectionSocket;
}
// 向其他客服端发送数据
bytesSent = send(tmpSocket, sendData.c_str(), sendData.size()+1,0);
if( bytesSent == SOCKET_ERROR){
cout<<"fail to send data to "<<destinationID<<" Client"<<WSAGetLastError()<<endl;
closesocket(tmpSocket);
}
else{
rtnData = "success to send data to " + destinationID +" Client#";
}
}
else if (strnicmp(message.c_str(),"Q",1) == 0 ){
// 释放接收数据缓存,关闭socket
pData->ifUsed = false;
HeapFree(GetProcessHeap(), 0 ,request);
closesocket(socket);
return 0;
}
if(rtnData != ""){
// 发送数据
bytesSent = send(socket, rtnData.c_str(), rtnData.size()+1,0);
// 判断是否成功
if( bytesSent == SOCKET_ERROR){
cout<<"\tCommunicationThread\tsend error "<<WSAGetLastError()<<endl;
closesocket(socket);
}
cout<<"\tCommunicationThread("<<Tid<<")\tsend data: "<<rtnData<<endl;
}
}
}
}
int main()
{
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET; // 监听socket
SOCKET ClientSocket = INVALID_SOCKET; // 连接socket
struct addrinfo *result = NULL;
struct addrinfo server;
int tmpResult; // 保存返回结果
tmpResult = WSAStartup(MAKEWORD(2,2), &wsaData); // 加载Ws2_32.dll
if (tmpResult != 0)
{
cout<<"WSAStartup failed"<<tmpResult<<endl;
}
ZeroMemory(&server, sizeof(server));
server.ai_family = AF_INET; // ipv4
server.ai_socktype = SOCK_STREAM; // 面向链接的TCP
server.ai_protocol = IPPROTO_TCP; // TCP 协议
server.ai_flags = AI_PASSIVE;
tmpResult = getaddrinfo(NULL, DEFAULT_PORT, &server, &result);
if ( tmpResult != 0 )
{
cout<<"Failed to get addrinfo"<<tmpResult<<endl;
WSACleanup();
}
// 创建监听 Socket
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET)
{
cout<<"Failed to create a socket"<<WSAGetLastError()<<endl;
freeaddrinfo(result);
WSACleanup();
}
// 绑定到端口
tmpResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (tmpResult == SOCKET_ERROR)
{
cout<<"Failed to bind "<<WSAGetLastError()<<endl;
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
}
cout<<"bind "<<endl;
freeaddrinfo(result);
// 开始监听
tmpResult = listen(ListenSocket, SOMAXCONN);
cout<<"start to listen... "<<endl;
if (tmpResult == SOCKET_ERROR)
{
cout<<"Failed to listen "<<WSAGetLastError()<<endl;
closesocket(ListenSocket);
WSACleanup();
}
while (1)
{
cout<<"ready to accept "<<endl;
ClientSocket = accept(ListenSocket, NULL, NULL); // 收到连接请求
cout<<"Having accepted a connection "<<endl;
int position;
// 连接失败
if (ClientSocket == INVALID_SOCKET)
{
cout<<"Failed to accept "<<WSAGetLastError()<<endl;
closesocket(ListenSocket);
break;
}
// 连接成功
else
{
for(position=0; position<CAPACITY; position++)
{
if(Client[position].ifUsed == false){
Client[position].connectionSocket = ClientSocket;
char* id = new char(10);
itoa(position,id,10);
Client[position].id = id;
Client[position].ifUsed = true;
break;
}
}
string rtnData = "";
string tmp = "";
tmp = "HTTP/1.0 200 Document
- 1
- 2
- 3
- 4
前往页