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;
}

Support free Wi-Fi

openwireless.org

Support free maps

openstreetmap.org