Relay Server Using C++/.NET
I wrote a small Relay server program using C++ and the .NET API. This was just done as an example for someone on IRC, so it's not very fancy. All it does is accept a line of text from one client and forward it to all other connected clients. The code is below.
// RelayServer.cpp : main project file.
#include "stdafx.h"
using System::Net::IPEndPoint;
using System::Net::Sockets::Socket;
using System::Net::Sockets::NetworkStream;
using System::Net::Sockets::AddressFamily;
using System::Net::Sockets::SocketType;
using System::Net::Sockets::ProtocolType;
using System::Net::IPAddress;
using System::IO::Stream;
using System::IO::StreamReader;
using System::IO::StreamWriter;
using System::Collections::Generic::List;
using System::String;
using System::Console;
ref class Client;
Client ^locateClientBySocket(List<Client^>^ clientList, Socket ^s);
ref class Client {
public:
Socket ^socket;
StreamReader ^reader;
StreamWriter ^writer;
Client(Socket ^s){
NetworkStream ^ns=gcnew NetworkStream(s);
socket = s;
reader = gcnew StreamReader(ns);
writer = gcnew StreamWriter(ns);
}
Socket ^getSocket(){
return socket;
}
StreamReader ^getReader(){
return reader;
}
StreamWriter ^getWriter(){
return writer;
}
};
int main(array<System::String ^> ^args)
{
List<Client^>^ clientList=gcnew List<Client^>();
Socket ^server;
server = gcnew Socket(AddressFamily::InterNetwork, SocketType::Stream, ProtocolType::Tcp);
IPEndPoint ^anyAddr;
anyAddr = gcnew IPEndPoint(IPAddress::Any, 4488);
server->Bind(anyAddr);
server->Listen(128);
do {
List<Socket^>^ readList=gcnew List<Socket^>();
List<Socket^>^ writeList=gcnew List<Socket^>();
List<Socket^>^ exceptList=gcnew List<Socket^>();
for each (Client ^c in clientList){
Socket ^s=c->getSocket();
readList->Add(s);
writeList->Add(s);
exceptList->Add(s);
}
readList->Add(server);
Socket::Select(readList, writeList, exceptList, -1);
if (readList->Count > 0){
for (int i=0; i<readList->Count; i++){
if (readList[i] == server){
Client ^c=gcnew Client(server->Accept());
clientList->Add(c);
}
else {
Socket ^s=readList[i];
Client ^thisClient=locateClientBySocket(clientList, s);
String ^l=thisClient->getReader()->ReadLine();
if (l == nullptr || l->Length == 0){
//Connection is closed
s->Close();
clientList->Remove(thisClient);
}
else {
Console::WriteLine("Received line " + l);
for each (Client ^otherClient in clientList){
if (otherClient != thisClient){
StreamWriter ^writer=otherClient->getWriter();
writer->WriteLine(l);
writer->Flush();
}
}
}
}
}
}
} while (true);
Console::WriteLine(L"Hello World");
return 0;
}
Client ^locateClientBySocket(List<Client^>^ clientList, Socket ^s){
for each (Client ^c in clientList){
if (c->getSocket() == s){
return c;
}
}
return nullptr;
}