I've got a client - server code going on at the moment while working on my thesis. And I can spawn a connection and send data, but as soon as the client disconnects and tries to reconnect everything goes sideways and I can't seem to figure out why. Too many exceptions are being thrown and I just have no idea where to start catching them all. What am doing wrong or not doing that isn't allowing nether client nor server to handle disconnections properly ?!
This is my ServerSide Code:
using System;
using System.Net;
using System.Net.Sockets;
namespace Server.Networking
{
public class ServerSocket
{
private Socket _socket;
Byte[] _buffer = new byte[61144];
public ServerSocket()
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Bind(int port)
{
_socket.Bind(new IPEndPoint(IPAddress.Any, port));
}
public void Listener(int backlog)
{
_socket.Listen(backlog);
}
public void Accept()
{
_socket.BeginAccept(AcceptedCallback, null);
}
private void AcceptedCallback(IAsyncResult result)
{
try
{
Socket clientSocket = _socket.EndAccept(result);
if (clientSocket.Connected)
{
Console.WriteLine("Client has connected!");
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
Accept();
}
else
{
Console.WriteLine("Client hasn't connected!");
return;
}
}catch(SocketException ex)
{
Console.WriteLine(ex.Message);
close(clientSocket);
}
}
private void ReceivedCallback(IAsyncResult result)
{
try
{
Socket clientSocket = result.AsyncState as Socket;
SocketError SE;
int bufferSize = clientSocket.EndReceive(result, out SE);
if (bufferSize > 0)
{
if (SE == SocketError.Success)
{
byte[] packet = new byte[bufferSize];
Array.Copy(_buffer, packet, packet.Length);
Console.WriteLine("Handling packet from IP:" + clientSocket.RemoteEndPoint.ToString());
//Handle packet stuff here.
PacketHandler.Handle(packet, clientSocket);
_buffer = new byte[61144];
clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, clientSocket);
}
else
{
close(clientSocket);
}
}
else
{
Console.WriteLine("Probably received bad data.");
close(clientSocket);
}
}
catch (SocketException ex)
{
Console.WriteLine(ex.Message);
close(clientSocket);
}
}
public void close(Socket sock)
{
Console.WriteLine("Closing socket for IP:" + sock.RemoteEndPoint.ToString() + " and releasing resources.");
sock.Dispose();
sock.Close();
}
}
}
And this is my ClientSide Code:
using System;
using System.Net;
using System.Linq;
using System.Net.Sockets;
using Client.Networking.Packets;
using System.Net.NetworkInformation;
using Client.Networking.Packets.Request;
namespace Client.Networking
{
public class ClientSocket
{
private Socket _socket;
private byte[] _buffer;
public delegate void RaiseConnect(object source, TextArgs e);
public static event EventHandler Disconnected;
private static void RaiseDisconnect()
{
EventHandler handler = Disconnected;
if(handler !=null)
{
handler(null, EventArgs.Empty);
}
}
public ClientSocket()
{
udpbroadcast.Connect += new RaiseConnect(OnConnectRaise);
}
public string machineIP()
{
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork).ToString();
}
private void OnConnectRaise(object sender, TextArgs e)
{
CheckRegisteredRequest computer_name = new CheckRegisteredRequest(Environment.MachineName.ToString() + "," + machineIP());
Connect(e.Message, 6556);
Send(computer_name.Data);
}
public void Connect(string ipAddress, int port)
{
string ip = ipAddress;
int porT = port;
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult result =_socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), port), ConnectCallback, null);
bool success = result.AsyncWaitHandle.WaitOne(5000, true);
if(!success)
{
_socket.Close();
Console.WriteLine("Failed to connect to server. Trying again.");
Connect(ip, port);
}
}
private void ConnectCallback(IAsyncResult result)
{
try {
if (_socket.Connected)
{
Console.WriteLine("Connected to the server!");
_buffer = new byte[61144];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, null);
}
else
{
Console.WriteLine("Could not connect.");
Close(_socket);
}
}
catch(SocketException ex)
{
Console.WriteLine("ClientSocket ConnectCallback - "+ex.Message);
Close(_socket);
}
}
private void ReceivedCallback(IAsyncResult result)
{
try
{
SocketError SE;
int buflength = _socket.EndReceive(result, out SE);
if (buflength > 0)
{
if(SE == SocketError.Success)
{
byte[] packet = new byte[buflength];
Array.Copy(_buffer, packet, packet.Length);
//Handle the Package
PacketHandler.Handle(packet, _socket);
_buffer = new byte[61144];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, null);
}
else
{
Close(_socket);
}
}
else
{
Close(_socket);
}
}
catch (Exception ex)
{
Console.WriteLine("ClientSocket ReceivedCallback - " + ex.Message);
Close(_socket);
}
}
public void Send(byte[] data)
{
byte[] send = new byte[data.Length];
send = data;
if( _socket.Connected)
{
_socket.Send(data);
}
else
{
Console.WriteLine("Not connected yet!");
Close(_socket);
}
}
public bool connectionStatus()
{
return _socket.Connected;
}
public static void Close(Socket sock)
{
Console.WriteLine("Closing the socket and releasing resources.");
sock.Dispose();
sock.Close();
RaiseDisconnect();
}
}
}