📄 chatsvr.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "chatsvr.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TAWChatServerForm *AWChatServerForm;
//---------------------------------------------------------------------------
__fastcall TAWChatServerForm::TAWChatServerForm(TComponent* Owner)
: TForm(Owner)
{
Application->OnIdle = IdleEventResponse;
CurrentServerStatus = SS_NOT_RUNNING;
MainServerSocket->Port = CHAT_SERVER_PORT;
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::IdleEventResponse(TObject *Sender, bool &Done){
if (CurrentServerStatus != SS_RUNNING){
StartStopServerMenuItem->Caption = "&Start";
} else {
StartStopServerMenuItem->Caption = "&Stop";
}
}
//---------------------------------------------------------------------------
void EntryTypeToText(LogEntryType let, AnsiString &text){
switch(let){
case LET_WARNING:{
text = "Warning";
break;
}
case LET_ERROR:{
text = "Error";
break;
}
case LET_SIGNON:{
text = "Sign-on";
break;
}
case LET_SIGNOFF:{
text = "Sign-off";
break;
}
default:{
text = "Unknown";
break;
}
}
}
//---------------------------------------------------------------------------
void TAWChatServerForm::AddLogEntry(LogEntryType let, AnsiString EntryText){
TListItem *item = LogEntryListView->Items->Add();
AnsiString entrytype;
EntryTypeToText(let, entrytype);
item->Caption = entrytype;
item->SubItems->Add(EntryText);
item->SubItems->Add(TDateTime::CurrentDateTime());
}
//---------------------------------------------------------------------------
void TAWChatServerForm::SetServerStatus(ServerStatus _serverstatus){
CurrentServerStatus = _serverstatus;
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::StartStopServerMenuItemClick(TObject *Sender)
{
AnsiString ss;
switch(CurrentServerStatus){
case SS_NOT_RUNNING:{
MainServerSocket->Open();
SetServerStatus(SS_RUNNING);
AddLogEntry(LET_WARNING, "Server started");
break;
}
case SS_RUNNING:{
MainServerSocket->Close();
SetServerStatus(SS_NOT_RUNNING);
AddLogEntry(LET_WARNING, "Server stopped");
break;
}
}
UpdateStatusBar();
}
//---------------------------------------------------------------------------
void TAWChatServerForm::AddConnectionToListView(TCustomWinSocket *ClientSocket){
//The first thing the client will send is the user's nickname
AnsiString UserNickName = "Unknown";
TListItem *TempItem = ConnectionsListView->Items->Add();
TempItem->Caption = UserNickName;
TDateTime CurrentDT(TDateTime::CurrentDateTime());
TempItem->SubItems->Add(ClientSocket->RemoteHost);
TempItem->SubItems->Add(CurrentDT);
TempItem->Data = ClientSocket;
}
//---------------------------------------------------------------------------
TListItem * TAWChatServerForm::ListItemBySocket(TCustomWinSocket *Socket){
for (int i = 0; i < ConnectionsListView->Items->Count; i++){
if (reinterpret_cast<TCustomWinSocket *>(ConnectionsListView->Items->Item[i]->Data) == Socket){
return ConnectionsListView->Items->Item[i];
}
}
return NULL;
}
//---------------------------------------------------------------------------
void TAWChatServerForm::RemoveConnectionFromListView(TCustomWinSocket *Socket){
TListItem *item = ListItemBySocket(Socket);
if (item)
ConnectionsListView->Items->Delete(item->Index);
}
//---------------------------------------------------------------------------
void TAWChatServerForm::SetUserBySocket(TCustomWinSocket *Socket, const AnsiString &UserNickName){
TListItem *item = ListItemBySocket(Socket);
if (item)
item->Caption = UserNickName;
}
//---------------------------------------------------------------------------
void TAWChatServerForm::GetUserBySocket(TCustomWinSocket *Socket, AnsiString &UserNickName){
TListItem *item = ListItemBySocket(Socket);
if (item)
UserNickName = item->Caption;
else
UserNickName = "Unknown";
}
//---------------------------------------------------------------------------
void TAWChatServerForm::UpdateStatusBar(bool DecUse/* = false*/){
switch(CurrentServerStatus){
case SS_NOT_RUNNING:{
AWChatServerStatusBar->SimpleText = "Press start to begin.";
break;
}
case SS_RUNNING:{
if (DecUse)
AWChatServerStatusBar->SimpleText = IntToStr(MainServerSocket->Socket->ActiveConnections - 1) + " current connection(s).";
else
AWChatServerStatusBar->SimpleText = IntToStr(MainServerSocket->Socket->ActiveConnections) + " current connection(s).";
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::MainServerSocketClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
Socket->Data = 0;
AddConnectionToListView(Socket);
UpdateStatusBar();
}
//---------------------------------------------------------------------------
void TAWChatServerForm::SendNotification(ServerNotification sn, AnsiString additional, TCustomWinSocket *ExcludeSocket){
AnsiString UserNickName;
GetUserBySocket(ExcludeSocket, UserNickName);
switch(sn){
case SN_LOGON:{
BroadcastMessage(UserNickName + " just signed on.", ExcludeSocket);
AddLogEntry(LET_SIGNON, UserNickName);
break;
}
case SN_LOGOFF:{
BroadcastMessage(UserNickName + " just signed off.", ExcludeSocket);
AddLogEntry(LET_SIGNOFF, UserNickName);
break;
}
case SN_PUBLIC_MSG:{
AnsiString msgtosend = "<" + UserNickName + "> " + additional;
BroadcastMessage(msgtosend, ExcludeSocket);
break;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::MainServerSocketClientDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
SendNotification(SN_LOGOFF, "", Socket);
RemoveConnectionFromListView(Socket);
UpdateStatusBar(true);
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::MainServerSocketClientError(TObject *Sender,
TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
AddLogEntry(LET_ERROR, "Socket error " + IntToStr(ErrorCode));
SendNotification(SN_LOGOFF, "", Socket);
ErrorCode = 0;
RemoveConnectionFromListView(Socket);
UpdateStatusBar(true);
}
//---------------------------------------------------------------------------
void TAWChatServerForm::BroadcastMessage(AnsiString Message, TCustomWinSocket *ExcludeSocket){
for (int i = 0; i < MainServerSocket->Socket->ActiveConnections; i++){
if (MainServerSocket->Socket->Connections[i] != ExcludeSocket){
MainServerSocket->Socket->Connections[i]->SendText(Message);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::MainServerSocketClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString UserNickName;
if (!Socket->Data){
UserNickName = Socket->ReceiveText();
int index = UserNickName.Pos("\n");
if (index > 1)
UserNickName.SetLength(index-1);
else
UserNickName = "Unknown or invalid " + IntToStr(Socket->SocketHandle);
SetUserBySocket(Socket, UserNickName);
Socket->Data = (void *)1;
AnsiString loginresponse = UserNickName + ", welcome to a simple chat server.";
Socket->SendText(loginresponse);
SendNotification(SN_LOGON, "", Socket);
} else {
AnsiString recvtxt = Socket->ReceiveText();
SendNotification(SN_PUBLIC_MSG, recvtxt, Socket);
}
}
//---------------------------------------------------------------------------
void __fastcall TAWChatServerForm::Exit1Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -