break;
}
case P2PMESSAGEACK:
{
// 傳送消息的回應
RecvedACK = true;
break;
}
case P2PTRASH:
{
// 對方傳送的打洞消息,忽略掉。
//do nothing ...
printf("Recv p2ptrash data\n");
break;
}
case GETALLUSER:
{
int usercount;
int fromlen = sizeof(remote);
int iread = recvfrom(PrimaryUDP, (char *)&usercount, sizeof(int), 0, (sockaddr *)&remote, &fromlen);
if(iread<=0)
{
throw Exception("Login error\n");
}
ClientList.clear();
cout<<"Have "<<usercount<<" users logined server:"<<endl;
for(int i = 0;i<usercount;i++)
{
stUserListNode *node = new stUserListNode;
recvfrom(PrimaryUDP, (char*)node, sizeof(stUserListNode), 0, (sockaddr *)&remote, &fromlen);
ClientList.push_back(node);
cout<<"Username:"<<node->userName<<endl;
in_addr tmp;
tmp.S_un.S_addr = htonl(node->ip);
cout<<"UserIP:"<<inet_ntoa(tmp)<<endl;
cout<<"UserPort:"<<node->port<<endl;
cout<<""<<endl;
}
break;
}
}
}
}
int main(int argc, char* argv[])
{
try
{
InitWinSock();
PrimaryUDP = mksock(SOCK_DGRAM);
BindSock(PrimaryUDP);
cout<<"Please input server ip:";
cin>>ServerIP;
cout<<"Please input your name:";
cin>>UserName;
ConnectToServer(PrimaryUDP, UserName, ServerIP);
HANDLE threadhandle = CreateThread(NULL, 0, RecvThreadProc, NULL, NULL, NULL);
CloseHandle(threadhandle);
OutputUsage();
for(;
{
char Command[COMMANDMAXC];
gets(Command);
ParseCommand(Command);
}
}
catch(Exception &e)
{
printf(e.GetMessage());
return 1;
}
return 0;
}
/* 異常類
*
* 檔案名:Exception.h
*
* 日期:2004.5.5
*
* 作者:shootingstars(zhouhuis22@sina.com)
*/
#ifndef __HZH_Exception__
#define __HZH_Exception__
#define EXCEPTION_MESSAGE_MAXLEN 256
#include "string.h"
class Exception
{
private:
char m_ExceptionMessage[EXCEPTION_MESSAGE_MAXLEN];
public:
Exception(char *msg)
{
strncpy(m_ExceptionMessage, msg, EXCEPTION_MESSAGE_MAXLEN);
}
char *GetMessage()
{
return m_ExceptionMessage;
}
};
#endif
/* P2P 程序傳輸傳輸協定
*
* 日期:2004-5-21
*
* 作者:shootingstars(zhouhuis22@sina.com)
*
*/
#pragma once
#include <list>
// 定義iMessageType的值
#define LOGIN 1
#define LOGOUT 2
#define P2PTRANS 3
#define GETALLUSER 4
// 伺服器連接阜
#define SERVER_PORT 2280
// Client登入時向伺服器傳送的消息
struct stLoginMessage
{
char userName[10];
char password[10];
};
// Client註銷時傳送的消息
struct stLogoutMessage
{
char userName[10];
};
// Client向伺服器請求另外一個Client(userName)向自己方向傳送UDP打洞消息
struct stP2PTranslate
{
char userName[10];
};
// Client向伺服器傳送的消息格式
struct stMessage
{
int iMessageType;
union _message
{
stLoginMessage loginmember;
stLogoutMessage logoutmember;
stP2PTranslate translatemessage;
}message;
};
// 客戶節點訊息
struct stUserListNode
{
char userName[10];
unsigned int ip;
unsigned short port;
};
// Server向Client傳送的消息
struct stServerToClient
{
int iMessageType;
union _message
{
stUserListNode user;
}message;
};
//======================================
// 下面的傳輸協定用於客戶端之間的通信
//======================================
#define P2PMESSAGE 100 // 傳送消息
#define P2PMESSAGEACK 101 // 收到消息的回應
#define P2PSOMEONEWANTTOCALLYOU 102 // 伺服器向客戶端傳送的消息
// 希望此客戶端傳送一個UDP打洞包
#define P2PTRASH 103 // 客戶端傳送的打洞包,接收端應該忽略此消息
// 客戶端之間傳送消息格式
struct stP2PMessage
{
int iMessageType;
int iStringLen; // or IP address
unsigned short Port;
};
using namespace std;
typedef list<stUserListNode *> UserList;
源碼下載:http://www.lihuasoft.net/source/show.php?id=3644