rendered paste bodyusing System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TcpSock
{
class TcpSock
{
int tcpIndx = 0;
int tcpByte = 0;
// 4mb Buffer (see if there are better ways to initialize a large recieve buffer)
byte[] tcpRecv = new byte[4096*1024];
////////////////////////////////////////
public Socket tcpSock;
////////////////////////////////////////
public String alias;
public int Recv(ref string tcpRead)
{
tcpByte = tcpSock.Available;
if (tcpByte > tcpRecv.Length - tcpIndx)
tcpByte = tcpRecv.Length - tcpIndx;
tcpByte = tcpSock.Receive(tcpRecv, tcpIndx, tcpByte,
SocketFlags.Partial);
tcpRead = Encoding.UTF8.GetString
(tcpRecv, tcpIndx, tcpByte);
tcpIndx += tcpByte;
return tcpRead.Length;
}
public void FlushBuffer()
{
tcpByte = 0;
tcpIndx = 0;
tcpRecv = new byte[4096 * 1024];
}
public int SendLine(string tcpWrite)
{
tcpSock.Send(Encoding.UTF8.GetBytes(tcpWrite+"\n"));
FlushBuffer();
return 0;
}
public int Send(string tcpWrite)
{
tcpSock.Send(Encoding.UTF8.GetBytes(tcpWrite));
FlushBuffer();
return 0;
}
}
class Tcp
{
static void privateMessage(TcpSock currentClient, String recievedLine, ArrayList Client)
{
foreach (TcpSock aClientSocket in Client)
{
if (recievedLine.Substring(3).Trim().StartsWith(aClientSocket.alias))
{
String message = recievedLine.Substring(3).Trim().Substring(aClientSocket.alias.Length);
aClientSocket.SendLine("[" + currentClient.alias + "]: " + message);
currentClient.SendLine("PM > " + aClientSocket.alias + ": " + message);
Console.WriteLine("{0} sent {1} a Private Message", currentClient.alias, aClientSocket.alias);
}
}
}
static void newNick(TcpSock currentClient, String alias, ArrayList Client)
{
currentClient.SendLine("You are now called " + alias);
foreach (TcpSock aClientSocket in Client)
{
aClientSocket.SendLine(currentClient.alias + " is now known as " + alias);
}
currentClient.alias = alias;
}
static void meMessage(TcpSock currentClient, String message, ArrayList Client)
{
Console.WriteLine("{0} {1}", currentClient.alias, message);
foreach (TcpSock aClientSocket in Client)
{
aClientSocket.SendLine(currentClient.alias + message);
}
}
static void listUsers(TcpSock currentClient, ArrayList Client)
{
Console.WriteLine("{0} made a userlist request", currentClient.alias);
currentClient.SendLine("Users...:");
foreach (TcpSock aClientSocket in Client)
{
currentClient.SendLine(aClientSocket.alias);
}
}
static void showHelp(TcpSock currentClient)
{
currentClient.SendLine("Help...");
currentClient.SendLine("/who ... List connected users");
currentClient.SendLine("/list ... -\"- --\"-- -\"-");
currentClient.SendLine("/nick ... Set your chat nickname");
currentClient.SendLine("/me ... e.g. /me waves sends 'nickname waves'");
Console.WriteLine("{0} requested help.", currentClient.alias);
}
static void kick(TcpSock currentClient, String recievedLine, ArrayList Client)
{
foreach (TcpSock aClientSocket in Client)
{
if (aClientSocket.alias == recievedLine.Substring(5).Trim())
{
int idx = Client.IndexOf(aClientSocket);
Console.WriteLine("{0} kicked {1}", currentClient.alias, aClientSocket.alias);
aClientSocket.SendLine("You were kicked by " + currentClient.alias);
currentClient.SendLine("You kicked " + aClientSocket.alias);
aClientSocket.tcpSock.Shutdown(SocketShutdown.Both);
aClientSocket.tcpSock.Close();
Client.RemoveAt(idx);
break;
}
}
}
static void clearClientConsole(TcpSock currentClient, String recievedLine, ArrayList Client)
{
foreach (TcpSock aClientSocket in Client)
{
if (aClientSocket.alias == recievedLine.Substring(6).Trim())
{
int idx = Client.IndexOf(aClientSocket);
Console.WriteLine("{0} cleared {1}'s chat log", currentClient.alias, aClientSocket.alias);
aClientSocket.Send("&&clr");
currentClient.SendLine("You cleared " + aClientSocket.alias + "'s chat log");
}
}
}
[STAThread]
static void Main()
{
////////////////////////////////////////////////////////////////////////////////////////////
///class IPHostEntry : Stores information about the Host and is required
///for IPEndPoint.
///class IPEndPoint : Stores information about the Host IP Address and
///the Port number.
///class TcpSock : Invokes the constructor and creates an instance.
///class ArrayList : Stores a dynamic array of Client TcpSock objects.
IPHostEntry Iphe = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint Ipep = new IPEndPoint(Iphe.AddressList[0], 4444);
Socket Server = new Socket(Ipep.Address.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
////////////////////////////////////////////////////////////////////////////////////////////
///Initialize
///Capacity : Maximux number of clients able to connect.
///Blocking : Determines if the Server TcpSock will stop code execution
///to receive data from the Client TcpSock.
///Bind : Binds the Server TcpSock to the Host IP Address and the Port Number.
///Listen : Begin listening to the Port; it is now ready to accept connections.
ArrayList Client = new ArrayList();
ArrayList Nicks = new ArrayList();
string recievedLine = null;
Client.Capacity = 256;
Server.Blocking = false;
Server.Bind(Ipep);
Server.Listen(32);
Console.WriteLine("{0}: listening to port {1}", Dns.GetHostName(),
Ipep.Port);
////////////////////////////////////////////////////////////////////////////////////////////
///Main loop
///1. Poll the Server TcpSock; if true then accept the new connection.
///2. Poll the Client TcpSock; if true then receive data from Clients.
while (true)
{
//Accept
if (Server.Poll(0, SelectMode.SelectRead))
{
int i = Client.Add(new TcpSock());
TcpSock currentClient = ((TcpSock)Client[i]);
currentClient.tcpSock = Server.Accept();
currentClient.alias = "Client " + i;
currentClient.SendLine("Welcome to the test socket server.");
currentClient.SendLine("/help for server commands.");
for (int j = 0; j < Client.Count; j++)
{
TcpSock aClientSocket = ((TcpSock)Client[j]);
aClientSocket.SendLine(currentClient.alias + " connected.");
}
Console.WriteLine("{0} connected.", currentClient.alias);
}
for (int i = 0; i < Client.Count; i++)
{
TcpSock currentClient = ((TcpSock)Client[i]);
if (currentClient.tcpSock.Poll(0, SelectMode.SelectRead))
{
if (currentClient.Recv(ref recievedLine) > 0)
{
if (!recievedLine.StartsWith("/"))
{
Console.WriteLine("{0}: {1}", currentClient.alias, recievedLine);
foreach (TcpSock aClientSocket in Client)
{
aClientSocket.Send(currentClient.alias + ": " + recievedLine);
}
}
else
{
String[] command = recievedLine.Split(new Char[]{' ','\n','\r'});
switch (command[0])
{
case "/nick":
{
newNick(currentClient, recievedLine.Substring(5).Trim(), Client);
break;
}
case "/me":
{
meMessage(currentClient, recievedLine.Substring(3), Client);
break;
}
case "/who":
case "/list":
{
listUsers(currentClient, Client);
break;
}
case "/help":
{
showHelp(currentClient);
break;
}
case "/pm":
{
privateMessage(currentClient, recievedLine, Client);
break;
}
case "/stfu":
case "/gtfo":
{
kick(currentClient, recievedLine, Client);
break;
}
case "/clear":
{
clearClientConsole(currentClient, recievedLine, Client);
break;
}
default:
break;
}
}
}
else
{
currentClient.tcpSock.Shutdown(SocketShutdown.Both);
currentClient.tcpSock.Close();
Client.RemoveAt(i);
Console.WriteLine("{0} disconnected.", currentClient.alias);
foreach (TcpSock aClientSocket in Client)
{
aClientSocket.Send(currentClient.alias + " disconnected.\n");
}
}
}
}
}
}
}
}