C# Creating chat rooms with multi client-server Sockets - c#

Good afternoon, i've been trying to make a system kinda like skype in terms of convo groups, being able to enter a group and chatting with others that were online only within that group, issue is i dont know how i could separate this chat room into several ones and making them independent from each other with just one server
Overall, im trying to have multi chat rooms with one server while being able to save one's conversation chat log and be able to read it back
The current code i have works only as 1 general chat room
Server Side:
static void Main(string[] args)
{
Socket newSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Ip);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 6000);
newSocket.Bind(endPoint);
newSocket.Listen(10);
Console.Write("Waiting...\n");
while (true)
{
Socket auxSocket = newSocket.Accept();
ThreadLab a = new ThreadLab(auxSocket);
Thread novaThread = new Thread(new ThreadStart(a.Connect));
novaThread.Start();
}
}
The ThreadLab Class:
private Socket socket;
static int nmrUsers = 0;
static int indice;
static Socket[] listaSockets = new Socket[10];
static ArrayList listaUtilizadores = new ArrayList();
public ThreadLab(Socket s)
{
socket = s;
listaSockets[indice++] = s;
}
public void Connect()
{
IPEndPoint aux = (IPEndPoint)socket.RemoteEndPoint;
Console.Write("Client " + aux.Address.ToString() + " connected\n");
}
And the client side that will have the reader and writer:
private static Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Ip);
private static ThreadStart tSReader;
private static ThreadStart tSWriter;
private static Thread tReader;
private static Thread tWriter;
private static string nome;
static void Main(string[] args)
{
IPEndPoint clientEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6000);
tSReader = new ThreadStart(reader);
tSWriter = new ThreadStart(writer);
tReader = new Thread(tSReader);
tWriter = new Thread(tSWriter);
try
{
client.Connect(clientEndPoint);
}
catch (SocketException e)
{
Console.WriteLine(e.ToString());
Console.ReadLine();
return;
}
tReader.Start();
tWriter.Start();
}
public static void writer()
{
string str;
byte[] data = new byte[1024];
nome = Console.ReadLine();
data = Encoding.ASCII.GetBytes(nome);
client.Send(data, data.Length, SocketFlags.None);
do
{
str = Console.ReadLine();
data = Encoding.ASCII.GetBytes(str);
client.Send(data, data.Length, SocketFlags.None);
} while (str != "exit");
client.Shutdown(SocketShutdown.Both);
tReader.Abort();
client.Close();
}
public static void reader()
{
byte[] data = new byte[1024];
int recv;
while (true)
{
try
{
recv = client.Receive(data);
}
catch (Exception e)
{
Console.WriteLine("Erro: " + e.Message);
Console.ReadLine();
break;
}
Console.WriteLine("\n" + Encoding.ASCII.GetString(data, 0, recv));
}
}
}
Someone can help me?

Related

UDP Connection between two PC's (requested address is not valid)

first - my program works without any problems in a Network with a router. Now I need to establish a connection between two PC's with static IP's, but I get the following message: the requested address is not valid in its context.
Some connect code:
namespace ConsoleUdpTest
{
class Program
{
public static Socket socketReceiver;
public static Socket socketSender;
private const int bufSize = 8 * 1024;
private static State state = new State();
private static EndPoint epFrom = new IPEndPoint(IPAddress.Any, 0);
private static EndPoint epTo = new IPEndPoint(IPAddress.Any, 0);
private static AsyncCallback recv = null;
private static string udpBindingIp = "192.168.2.1";
private static int udpBindingPort = 27000;
private static string udpOutIp = "self";
private static int udpOutPort = 0;
static void Main(string[] args)
{
socketReceiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socketReceiver.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
socketReceiver.Bind(new IPEndPoint(IPAddress.Parse(udpBindingIp), udpBindingPort));
socketSender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socketSender.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.ReuseAddress, true);
Receive();
while (true)
{
System.Console.ReadKey();
};
}
private static void Send(string text)
{
try
{
socketSender.Connect(epTo);
byte[] data = Encoding.ASCII.GetBytes(text);
socketSender.BeginSend(data, 0, data.Length, SocketFlags.None, (ar) =>
{
State so = (State)ar.AsyncState;
int bytes = socketSender.EndSend(ar);
}, state);
}
catch (Exception e)
{
string s = e.Message;
}
}
private static void Receive()
{
socketReceiver.BeginReceiveFrom(state.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv = (ar) =>
{
try
{
State so = (State)ar.AsyncState;
int bytes = socketReceiver.EndReceiveFrom(ar, ref epFrom);
socketReceiver.BeginReceiveFrom(so.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv, so);
string message = Encoding.ASCII.GetString(so.buffer, 0, bytes);
if (udpOutIp.Contains("self"))
{
epTo = epFrom;
}
Send(message);
if (message.Contains("(") && message.Contains(")"))
{
Console.WriteLine("contains ( and )");
string command = message.TrimStart();
command = command.Substring(0, command.IndexOf("("));
string parameters = message.Substring(message.IndexOf("(") + 1, message.IndexOf(")") - message.IndexOf("(")-1);
//if (BleCommands.Exists(o => command.Contains(o)))
Console.WriteLine(command);
Console.WriteLine(parameters);
}
Console.WriteLine("in: " + message);
}
catch (Exception e)
{
string s = e.Message;
Console.WriteLine("Exception: " + s);
}
}, state);
}
public class State
{
public byte[] buffer = new byte[bufSize];
}
}
}
Server IP: 192.168.2.1 Subnetmask: 255.255.255.0
Client IP: 192.168.2.2 Subnetmask: 255.255.255.0
Ping the Server works without any problems

How to add multiple clients to a server in c#?

My Client Source Code :
public partial class Form1 : Form
{
string serverip = "localHost";
int port = 160;
public Form1()
{
InitializeComponent();
}
private void Submit_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient(serverip, port);
int byteCount = Encoding.ASCII.GetByteCount(Message.Text);
byte[] sendData = new byte[byteCount];
sendData = Encoding.ASCII.GetBytes(Message.Text);
NetworkStream stream = client.GetStream();
stream.Write(sendData, 0, sendData.Length);
stream.Close();
client.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
My server
class Program
{
static void Main(string[] args)
{
IPAddress ip = Dns.GetHostEntry("localHost").AddressList[0];
TcpListener server = new TcpListener(ip, 160);
TcpClient client = default(TcpClient);
try
{
server.Start();
Console.WriteLine("The server has started successfully");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
while (true)
{
client = server.AcceptTcpClient();
byte[] receivedBuffer = new byte[100];
NetworkStream stream = client.GetStream();
stream.Read(receivedBuffer, 0, receivedBuffer.Length);
StringBuilder msg = new StringBuilder();
foreach (byte b in receivedBuffer)
{
if (b.Equals(59))
{
break;
}
else
{
msg.Append(Convert.ToChar(b).ToString());
}
}
Console.WriteLine(msg.ToString() + msg.Length);
}
}
}
Essentially i want make it so i can have multiple clients on the server sending a message from different ip addresses of course. I have been using c# a year now mostly in school and I am above average at best at it.
First time asking question so sorry if its in wrong format

C# TCP Server combining received data

I'm working on a rough TCP Server/Client. It works like this:
Client sends message to server > Server sends all user data to each client. I have this in a loop as I'm going to use this transfer of data for multiplayer in a game. However, for some reason my server will combine incoming data into one string instead of reading it line by line. For example, it should read something like
john:0|0
for user data, but instead it reads like john:0|0john:0|0john:0|0john:0|0
I've tried setting a delay on sending and receiving, but it only seems to work if I delay more than 100ms.
Server
class Program
{
private static Socket _serverSocket;
private static readonly List<Socket> _clientSockets = new List<Socket>();
private const int _BUFFER_SIZE = 2048;
private const int _PORT = 100;
private static readonly byte[] _buffer = new byte[_BUFFER_SIZE];
public static bool clientConnected = false;
public static Socket current;
public static int delay = 100; //65
public static string username = "";
public static int dataSent = 0;
public static int dataReceived = 0;
public static List<Player> players = new List<Player>();
static void Main()
{
Console.Title = "Server";
SetupServer();
Console.ReadLine(); // When we press enter close everything
CloseAllSockets();
}
private static void SetupServer()
{
Console.WriteLine("Setting up server...");
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, _PORT));
_serverSocket.Listen(5);
_serverSocket.BeginAccept(AcceptCallback, null);
Console.WriteLine("Server setup complete");
Console.WriteLine("Listening on port: " + _PORT);
}
private static void CloseAllSockets()
{
foreach (Socket socket in _clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
_serverSocket.Close();
}
private static void AcceptCallback(IAsyncResult AR)
{
Socket socket;
try
{
socket = _serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
{
return;
}
_clientSockets.Add(socket);
socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
Console.WriteLine("Client connected: " + socket.RemoteEndPoint);
_serverSocket.BeginAccept(AcceptCallback, null);
clientConnected = true;
}
private static void ReceiveCallback(IAsyncResult AR)
{
current = (Socket)AR.AsyncState;
int received = 0;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Console.WriteLine("Client forcefully disconnected");
current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway
_clientSockets.Remove(current);
return;
}
byte[] recBuf = new byte[received];
Array.Copy(_buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
if (text.Contains("newuser:"))
{
string newuser = text.Replace("newuser:", "");
Player newPlayer = new Player(newuser, current.RemoteEndPoint.ToString());
players.Add(newPlayer);
SendString("newuser:" + newuser);
Console.WriteLine(newuser + " has joined the game.");
}
else
{
Console.WriteLine(text); //This is where the client text gets mashed together
}
current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
}
public static void SendString(string message)
{
try
{
byte[] data = Encoding.ASCII.GetBytes(message.ToString());
current.Send(data);
//current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
dataSent++;
}
catch (Exception ex)
{
Console.WriteLine("Client disconnected!" + ex.Message);
}
Console.WriteLine(dataSent);
}
}
Client.cs
public static class Client
{
public static string Username = "null";
public static int delay = 85;
public static bool hasLoggedin = false;
public static int dataSent = 0;
private static readonly Socket _clientSocket = new Socket
(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private const int port = 100;
public static void Init()
{
Console.Title = "Client";
ConnectToServer();
Exit();
}
private static void ConnectToServer()
{
int attempts = 0;
while (!_clientSocket.Connected)
{
try
{
attempts++;
Console.Write("Username: ");
//Username = Console.ReadLine();
Username = "Matt";
LocalPlayer.username = Username;
Console.Write("IP: ");
string ip = "192.168.0.2";
Console.WriteLine("Port[default]: " + port);
Console.WriteLine("Connection attempt to " + ip + ": " + attempts + " attempts");
IPAddress ipAd = IPAddress.Parse(ip);
_clientSocket.Connect(ipAd, port);
}
catch (SocketException e)
{
Console.Clear();
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
Console.WriteLine("Connected!");
SendLoginPacket();
}
public static void SendLoginPacket()
{
if (hasLoggedin == false)
{
SendString("newuser:" + Username);
Thread.Sleep(delay);
hasLoggedin = true;
}
RequestLoop();
}
private static void RequestLoop()
{
while (true)
{
//SendData();
ReceiveResponse();
}
}
private static void Exit()
{
_clientSocket.Shutdown(SocketShutdown.Both);
_clientSocket.Close();
Environment.Exit(0);
}
public static void SendData()
{
string data = LocalPlayer.username + ":" + LocalPlayer.velocity.X + "|" + LocalPlayer.velocity.Y;
SendString(data);
}
private static void SendString(string text)
{
byte[] buffer = Encoding.ASCII.GetBytes(text);
Console.WriteLine("Sent: " + text);
_clientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
dataSent++;
Thread.Sleep(delay);
Console.WriteLine(dataSent);
}
private static void ReceiveResponse()
{
var buffer = new byte[2048];
int received = _clientSocket.Receive(buffer, SocketFlags.None);
if (received == 0) return;
var data = new byte[received];
Array.Copy(buffer, data, received);
string text = Encoding.ASCII.GetString(data);
if (text.Contains("newuser:"))
{
string str = text.Replace("newuser:", "");
if (!(str == LocalPlayer.username))
{
Player player = new Player(str, Globals.Content);
Globals.players.Add(player);
Console.WriteLine(str + " has joined the game.");
}
}
Console.WriteLine("Clients connected: " + Globals.players.Count());
}
}
How can I change the server so it reads incoming data one at a time, instead of mashing it into one big string?
EDIT: Note the LocalPlayer class is sending it's movement position using the Client class.
This is because the TCP/IP protocol provides the stream of the data (bytes). If the strings are not separated explicitly, they are "concatenated" because of "streaming".
It is required to "join" the messages using the "separator" when sending and "split" the messages using the "separator" when receiving. One of the following alternatives could be considered to implement the "separator" concept:
Introduce the "end-of-the-message" marker.
Introduce the message header which contains the length of the message.
The small article, TCP/IP client-server application: exchange with string messages, may be useful to understand the mentioned alternatives.
Update
I would like to recommend implementing the "messaging" appropriately.
Although it seems there is no the reason to compare the source code because it of its principal flaw (lack of "messaging" mechanism), the source code I have used to test the Client and the Server is attached.
Client
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
internal sealed class Program
{
private const int Port = 100;
private readonly Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private bool hasLoggedin;
private int dataSent;
public static void Main()
{
var client = new Program();
client.ConnectToServer();
client.Exit();
}
private void ConnectToServer()
{
int attempts = 0;
while (!clientSocket.Connected)
{
try
{
attempts++;
string ip = "127.0.0.1";
Console.WriteLine("Port[default]: " + Port);
Console.WriteLine("Connection attempt to " + ip + ": " + attempts + " attempts");
var address = IPAddress.Parse(ip);
clientSocket.Connect(address, Port);
}
catch (SocketException e)
{
Console.Clear();
Console.WriteLine(e.Message);
Console.ReadLine();
}
}
Console.WriteLine("Connected!");
SendLoginPacket();
}
private void SendLoginPacket()
{
if (hasLoggedin == false)
{
SendString("newuser:" + Guid.NewGuid());
hasLoggedin = true;
}
RequestLoop();
}
private void RequestLoop()
{
while (true)
{
SendData();
ReceiveResponse();
}
}
private void Exit()
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
private void SendData()
{
const string Data = "username:100|200";
SendString(Data);
}
private void SendString(string text)
{
byte[] buffer = Encoding.ASCII.GetBytes(text);
Console.WriteLine("Sent: " + text);
clientSocket.Send(buffer, 0, buffer.Length, SocketFlags.None);
dataSent++;
Console.WriteLine(dataSent);
}
private void ReceiveResponse()
{
var buffer = new byte[2048];
int received = clientSocket.Receive(buffer, SocketFlags.None);
if (received == 0)
{
return;
}
var data = new byte[received];
Array.Copy(buffer, data, received);
string text = Encoding.ASCII.GetString(data);
if (text.Contains("newuser:"))
{
string str = text.Replace("newuser:", string.Empty);
Console.WriteLine(str + " has joined the game.");
}
Console.WriteLine("Clients connected.");
}
}
Server
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
internal sealed class Program
{
private const int BufferSize = 2048;
private const int Port = 100;
private readonly List<Socket> clientSockets = new List<Socket>();
private readonly byte[] buffer = new byte[BufferSize];
private readonly List<Player> players = new List<Player>();
private Socket serverSocket;
private Socket current;
private int dataSent;
public static void Main()
{
var program = new Program();
program.SetupServer();
Console.ReadLine();
program.CloseAllSockets();
}
private void SetupServer()
{
Console.WriteLine("Setting up server...");
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, Port));
serverSocket.Listen(5);
serverSocket.BeginAccept(AcceptCallback, null);
Console.WriteLine("Server setup complete");
Console.WriteLine("Listening on port: " + Port);
}
private void CloseAllSockets()
{
foreach (Socket socket in clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
serverSocket.Close();
}
private void AcceptCallback(IAsyncResult AR)
{
Socket socket;
try
{
socket = serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException) // I cannot seem to avoid this (on exit when properly closing sockets)
{
return;
}
clientSockets.Add(socket);
socket.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, socket);
Console.WriteLine("Client connected: " + socket.RemoteEndPoint);
serverSocket.BeginAccept(AcceptCallback, null);
}
private void ReceiveCallback(IAsyncResult AR)
{
current = (Socket)AR.AsyncState;
int received = 0;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Console.WriteLine("Client forcefully disconnected");
current.Close(); // Dont shutdown because the socket may be disposed and its disconnected anyway
clientSockets.Remove(current);
return;
}
byte[] recBuf = new byte[received];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
if (text.Contains("newuser:"))
{
string newuser = text.Replace("newuser:", string.Empty);
Player newPlayer = new Player(newuser, current.RemoteEndPoint.ToString());
players.Add(newPlayer);
SendString("newuser:" + newuser);
Console.WriteLine(newuser + " has joined the game.");
}
else
{
// This is where the client text gets mashed together.
Console.WriteLine(text);
}
current.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, current);
}
private void SendString(string message)
{
try
{
byte[] data = Encoding.ASCII.GetBytes(message.ToString());
current.Send(data);
// current.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, current);
dataSent++;
}
catch (Exception ex)
{
Console.WriteLine("Client disconnected!" + ex.Message);
}
Console.WriteLine(dataSent);
}
}
internal sealed class Player
{
public Player(string newuser, string toString)
{
}
}
Client output
Port[default]: 100
Connection attempt to 127.0.0.1: 1 attempts
Connected!
Sent: newuser:6b06f0a6-bdb0-4471-ac58-fa9c490b7555
1
Sent: username:100|200
2
6b06f0a6-bdb0-4471-ac58-fa9c490b7555username:100|200 has joined the game.
Clients connected.
Sent: username:100|200
3
Server output
Setting up server...
Server setup complete
Listening on port: 100
Client connected: 127.0.0.1:1082
1
6b06f0a6-bdb0-4471-ac58-fa9c490b7555username:100|200 has joined the game.
username:100|200

how can I make thread in TCP server multi client dialogue

I am working on multi thread server and clients written in C#.So Guide
me how can I make multi thread in server for multi client.
This is my Server Code
class Program
{
static byte[] Buffer
{
get;
set;
}
static void Main(string[] args)
{
Program obj = new Program();
Console.WriteLine("Server");
obj.server_reciver();
}
static Socket sck;
public void server_reciver()
{
try
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEndPoint;
localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 1);
sck.Bind(localEndPoint);
sck.Listen(100);
while (true)
{
Socket accepted = sck.Accept();
// Buffer = new byte[accepted.ReceiveBufferSize];
Buffer = new byte[accepted.SendBufferSize];
int bytesRead = accepted.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
//for (int i = 0; i < bytesRead; i++)
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
//Console.WriteLine(Buffer[i] + "\r\n");
}
//string strData = Encoding.ASCII.GetString(Buffer);
string strData = Encoding.ASCII.GetString(formatted);
Console.Write("From Client=>" + strData + "\n");
Console.WriteLine("Enter the text:");
string data = Console.ReadLine();
byte[] reply = Encoding.ASCII.GetBytes(data);
accepted.Send(reply);
//accepted.Close();
accepted.Close();
}
sck.Close();
Console.Read();
}
catch (Exception ex)
{
}
}
}
This is my Client side and I make more then one client here is one
class Program
{
static byte[] Buffer
{
get;
set;
}
static Socket sck;
static void Main(string[] args)
{
Program obj = new Program();
obj.client_send();
}
public void client_send()
{
while (true)
{
sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEndPoint;
localEndPoint = new IPEndPoint(IPAddress.Parse("182.188.247.244"), 1);
//localEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.45"), 1);
try
{
sck.Connect(localEndPoint);
}
catch
{
Console.Write("Unable to connect to remote end point!\r\n");
//Main(args);
}
try
{
Console.Write("Enter Text: ");
string text = Console.ReadLine();
byte[] data = Encoding.ASCII.GetBytes(text);
sck.Send(data);
Buffer = new byte[sck.SendBufferSize];
int bytesRead = sck.Receive(Buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = Buffer[i];
//Console.WriteLine(Buffer[i] + "\r\n");
}
string strData = Encoding.ASCII.GetString(formatted);
Console.Write("From Server=>" + strData + "\n");
sck.Close();
}
catch(Exception )
{
}
}
Console.ReadLine();
}
}
Typically, you would keep Socket accepted = sck.Accept(); on the main thread, but once a request is received you would pass it to another thread for servicing. This allows the main thread to listed to another incoming request. You can use ThreadPool.QueueUserWorkItem to move the work to a background thread. Note that making it multi-threaded is going to give you problems since the response is read from Console. How is each worker thread to know that it gets the right data? But I assume you'll replace that with real server logic.
At some point, you may find that this doesn't scale. You're using blocking IO calls (Send and Receive) so your threads will spend a lot of time waiting. Non-blocking IO would be ideal, but it is more complicated to write.

.NET Sockets suddenly stopped working

I wrote a TCP Socket server and client a few months ago in my current project and they've been working flawlessly since then. But as of today I simply cannot get a connection between two machines that has been communicating without a hickup for a long time.
The setup is very straight forward: Two machines ('A' and 'B') are connected directly via an ethernet cable (no switch in between). Machine 'A' is also connected to my home network which allows for Internet access. Machine 'B' is only connected to 'A'. I am running the TCP server on 'B' and the client on 'A'.
I'm using the asynchronous .NET Socket features (BeginAccept etc on the server end and BeginConnect etc in the client end). Having debugged both ends I can only confirm that the server end never seems to get a call from the client. I haven't touched the code and it still works between other machines.
Also, there's no other comms problems between the two machines. I'm using Input Director to share one set of keyboard/mouse and normal UNC paths works fine to browse one machine from the other.
I have tested different ports and I've brought down the firewalls on both sides for good measure. I have released/renewed the connections on both sides, rebooted both machines and every other dummy option I can think of.
I confess I'm not terribly network savvy so I'd very much appreciate a few hints on what to look for next as I'm now out of ideas on what to check next. (I'm pretty sure it's gotta be something really stupid I've just overlooked. ;O)
EDIT (sample 'spike' code)
On request I adapted Microsoft's sample Socket code and compressed it a bit (below). I then tested running both server and client ends on machine 'B' which worked fine but on machine 'A' the same thing happened. The client got no contact with the server end. Here's the code:
public static class SocketServer
{
private class StateObject
{
public Socket _workSocket;
public const int BufferSize = 1024;
public readonly byte[] _buffer = new byte[BufferSize];
public readonly StringBuilder _sb = new StringBuilder();
}
private static readonly ManualResetEvent _s_allDone = new ManualResetEvent(false);
public static void StartListening()
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, 11000);
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
_s_allDone.Reset();
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(acceptCallback, listener);
_s_allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static void acceptCallback(IAsyncResult ar)
{
_s_allDone.Set();
var listener = (Socket)ar.AsyncState;
var handler = listener.EndAccept(ar);
var state = new StateObject {_workSocket = handler};
handler.BeginReceive(state._buffer, 0, StateObject.BufferSize, 0, readCallback, state);
}
private static void readCallback(IAsyncResult ar)
{
var state = (StateObject)ar.AsyncState;
var handler = state._workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead <= 0)
return;
state._sb.Append(Encoding.ASCII.GetString(state._buffer, 0, bytesRead));
var content = state._sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
}
else
{
handler.BeginReceive(state._buffer, 0, StateObject.BufferSize, 0, readCallback, state);
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
public static class SocketClient
{
private class StateObject
{
public Socket _workSocket;
public const int BufferSize = 256;
public readonly byte[] _receiveBuffer = new byte[BufferSize];
public readonly StringBuilder _sb = new StringBuilder();
}
private const int RemotePort = 11000;
private static readonly ManualResetEvent _s_connectDone = new ManualResetEvent(false);
private static readonly ManualResetEvent _s_sendDone = new ManualResetEvent(false);
private static readonly ManualResetEvent _s_receiveDone = new ManualResetEvent(false);
// The response from the remote device.
private static String _s_response = String.Empty;
private static void startClient()
{
try
{
_s_connectDone.WaitOne(2000); // <-- gives server time to boot when on same machine
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var remoteEndPoint = new IPEndPoint(ipAddress, RemotePort);
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEndPoint, connectCallback, client);
_s_connectDone.WaitOne();
send(client, "This is a test<EOF>");
_s_sendDone.WaitOne();
receive(client);
_s_receiveDone.WaitOne();
Console.WriteLine("Response received : {0}", _s_response);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void connectCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint);
_s_connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void receive(Socket client)
{
try
{
var state = new StateObject {_workSocket = client};
client.BeginReceive(state._receiveBuffer, 0, StateObject.BufferSize, 0, receiveCallback, state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void receiveCallback(IAsyncResult ar)
{
try
{
var state = (StateObject)ar.AsyncState;
var client = state._workSocket;
var bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state._sb.Append(Encoding.ASCII.GetString(state._receiveBuffer, 0, bytesRead));
client.BeginReceive(state._receiveBuffer, 0, StateObject.BufferSize, 0, receiveCallback, state);
}
else
{
if (state._sb.Length > 1)
{
_s_response = state._sb.ToString();
}
_s_receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void send(Socket client, String data)
{
var byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, sendCallback, client);
}
private static void sendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
var bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
_s_sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main()
{
startClient();
return 0;
}
}

Categories