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
Related
I need to make an application to return me the hours of all customers connected to the socket server.
But my application can only communicate locally.
Example:
If Endpoint Server is: (192.168.0.1, 32000)
Endpoint Client is: (192.168.0.1, 32000)
They connect and comunnicate.
But
If Endpoint Server is: (192.168.0.1, 32000)
Endpoint Client is: (192.168.0.2, 32000)
They connect, but not comunnicate.
Server Code:
class Server:Sincronia
{
GetIP getip = new GetIP();
private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private List<Socket> ListaDeClientesSockets = new List<Socket>(); /*Lista de sockets para adicionar clientes*/
private List<string> ListaDeClients = new List<string>();
private List<string> ListaDeHoras = new List<string>();
private const int _BUFFER_SIZE = 2048;
private int _PORT;
private string Ip;
private byte[] _buffer = new byte[_BUFFER_SIZE];
public Server(string IP, int port) /*Construtor para inicialização do IP e da Porta*/
{
this.Ip = IP;
this._PORT = port;
}
public void Connect()
{
Console.WriteLine("Socket Server ON");
Console.WriteLine(getip.getIP());
_serverSocket.Bind(new IPEndPoint(IPAddress.Parse(getip.getIP()), _PORT));
_serverSocket.Listen(5);
_serverSocket.BeginAccept(AcceptCallback, null);
}
public void ShowAllClients()
{
Console.WriteLine("####################### " + ListaDeClientesSockets.Count + " #######################");
for (int i = 0; i < ListaDeClientesSockets.Count; i++)
{
int j = i + 1;
Console.WriteLine("Client : " + j + " IP : " + ListaDeClients[i]);
}
}
private void CloseConnections()
{
foreach (Socket socket in ListaDeClientesSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
_serverSocket.Close();
}
/// <summary>AcceptCallback método da classe Server
/// Evento realizado para aceitar conexões dos clientes adicionando em uma lista genérica
/// /// </summary>
private void AcceptCallback(IAsyncResult asyncronousResult)
{
Socket socket;
try
{
socket = _serverSocket.EndAccept(asyncronousResult);
}
catch (ObjectDisposedException)
{
return;
}
ListaDeClientesSockets.Add(socket);
ListaDeClients.Add(((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
Console.WriteLine("Client Connect " + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
_serverSocket.BeginAccept(AcceptCallback, null);
}
public void SendToALL(string text)
{
foreach(Socket socket in ListaDeClientesSockets.ToList())
{
ListaDeHoras.Clear();
byte[] dataByte = Encoding.ASCII.GetBytes(text);
socket.Send(dataByte);
}
}
/// <summary>ReceiveCallBack método da classe Server
/// Evento realizado para receber e enviar dados do cliente através de um IASyncResult
/// </summary>
private void ReceiveCallback(IAsyncResult asyncronousResult)
{
Socket current = (Socket)asyncronousResult.AsyncState;
int received;
try
{
received = current.EndReceive(asyncronousResult);
}
catch (SocketException) /*Catch realizado caso houver perca de conexão com o cliente*/
{
Console.WriteLine("Conexão com o cliente " + ((IPEndPoint) current.RemoteEndPoint).Address.ToString() + " perdida.");
current.Close();
ListaDeClients.Remove(((IPEndPoint)current.RemoteEndPoint).Address.ToString());
ListaDeClientesSockets.Remove(current);
return;
}
byte[] recBuf = new byte[received];
Array.Copy(_buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
Console.WriteLine("Received Text: " + text);
ListaDeHoras.Add(text);
current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
}
}
Program Server code:
class Program
{
static void Main(string[] args)
{
Console.Title = "Servidor";
Server server = new Server("localhost", 8000);
server.Connect();
while (true)
{
string text = Console.ReadLine();
if (text == "mostrar")
server.ShowAllClients();
else
server.SendToALL(text);
}
Console.ReadKey();
}
}
Client Code:
class Client
{
Socket socketClient;
static int port = 8000;
static string localhostIP = "127.0.0.1";
private const int _BUFFER_SIZE = 2048;
private byte[] _buffer = new byte[_BUFFER_SIZE];
private string IP;
public Client(string ip)
{
this.IP = ip;
}
public void Start()
{
IPEndPoint endp = new IPEndPoint(IPAddress.Parse(IP), port);
try
{
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketClient.BeginConnect(endp, new AsyncCallback(ConnectCALLBACK), socketClient);
Receive(socketClient);
}
catch
{
}
}
private void ConnectCALLBACK(IAsyncResult assynresult)
{
try
{
Socket client = (Socket)assynresult.AsyncState;
Console.WriteLine("Conectado");
client.EndConnect(assynresult);
}
catch(SocketException)
{
Console.WriteLine("Falta de conexão com o servidor, verifique sua conexão.");
}
}
public void Receive(Socket socket)
{
try
{
socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
}
catch
{
}
}
private void ReceiveCallback(IAsyncResult asyncronousResult)
{
Socket current = (Socket)asyncronousResult.AsyncState;
int received;
try
{
received = current.EndReceive(asyncronousResult);
}
catch (SocketException)
{
return;
}
byte[] recBuf = new byte[received];
Array.Copy(_buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
if(text == "clock")
{
string horas = DateTime.Now.ToString("dd-MM-yyyy HH:mm");
byte[] sended = Encoding.ASCII.GetBytes(horas);
current.Send(sended);
}
current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
}
}
I need the server type "clock" and this is sent to all clients.
And so that clients receive, clients send to the server their respective hours.
just replace your client start function with the following
public void Start()
{
IPEndPoint endp = new IPEndPoint(IPAddress.Parse(IP), port);
try
{
socketClient = new Socket(endp, SocketType.Stream, ProtocolType.Tcp);
socketClient.BeginConnect(endp, new AsyncCallback(ConnectCALLBACK), socketClient);
Receive(socketClient);
}
catch
{
}
}
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
I've been working on a chat for 2 people. everything is great (i have some exceptions to solve, but no big deal).
but the problem is, when i send a message from the client to server, then server to client, the server sends the last message it got from the client and only after you send again, it sends the right message and the other way around.
Client
private Socket _socket;
private byte[] _buffer;
private bool ok = false;
private ListBox _listbox;
public ClientSocket(ListBox list)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listbox = list;
}
public void Connect(string ipAddress, int port)
{
_socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ipAddress), port), ConnectedCallback, null);
if(ok)
Item("Connected to the server!");
else Item("Could not Connect to the server!");
}
public void SendMessage(string text)
{
_buffer = new byte[1024];
_buffer = Encoding.Default.GetBytes(text);
_socket.BeginSend(_buffer, 0, _buffer.Length, SocketFlags.None, SentCallback, null);
}
private void ConnectedCallback(IAsyncResult result)
{
if (_socket.Connected)
{
_socket.EndConnect(result);
_buffer = new byte[1024];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, null);
ok = true;
}
}
private void ReceivedCallback(IAsyncResult result)
{
//_buffer = new byte[1024];
int bufLength = _socket.EndReceive(result);
//byte[] packet = new byte[bufLength];
//Array.Copy(_buffer, packet, packet.Length);
Array.Resize(ref _buffer, bufLength);
Item(PacketHandler.Handle(_buffer, _socket));
//PacketHandler.Handle(packet, _socket);
_buffer = new byte[1024];
_socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, null);
}
private void SentCallback(IAsyncResult result)
{
_socket.EndSend(result);
//_buffer = new byte[1024];
}
public void Item(string text)
{
if (_listbox.InvokeRequired)
{
_listbox.Invoke(new Action<string>(Item), text);
return;
}
_listbox.Items.Add(text);
}
server
private Socket _socket;
private Socket _client;
private byte[] _buffer = new byte[1024];
private ListBox _listbox;
public ServerSocket(ListBox list)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_listbox = list;
}
public void Bind(int port)
{
_socket.Bind(new IPEndPoint(IPAddress.Any, port));
Item("Server Started");
}
public void Listen(int backlog)
{
_socket.Listen(backlog);
Item("Listening...");
}
public void Accept()
{
_socket.BeginAccept(AcceptedCallback, null);
}
public void SendMessage(string text)
{
_buffer = new byte[1024];
_buffer = Encoding.Default.GetBytes(text);
_client.BeginSend(_buffer, 0, _buffer.Length, SocketFlags.None, SentCallback, null);
}
private void AcceptedCallback(IAsyncResult result)
{
_client = _socket.EndAccept(result);
_buffer = new byte[1024];
_client.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, _client);
//_listbox.Items.Add("Accepted User" + _socket.LocalEndPoint.AddressFamily.ToString() + " ");
//Accept();
}
private void ReceivedCallback(IAsyncResult result)
{
try
{
//_client = result.AsyncState as Socket;
int bufLength = _client.EndReceive(result);
//byte[] packet = new byte[bufferSize];
//Array.Copy(_buffer, packet, packet.Length);
Array.Resize(ref _buffer, bufLength);
Item(PacketHandler.Handle(_buffer, _client));
//Item(PacketHandler.Handle(packet, clientSocket));
//_listbox.Items.Add(PacketHandler.Handle(packet, clientSocket));
_buffer = new byte[1024];
_client.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, ReceivedCallback, _client);
}
catch (SocketException)
{
Item(("User " + _client.LocalEndPoint.ToString() + " has disconnected"));
}
}
private void SentCallback(IAsyncResult result)
{
_client.EndSend(result);
//_buffer = new byte[1024];
}
public void Item(string text)
{
if (_listbox.InvokeRequired)
{
_listbox.Invoke(new Action<string>(Item), text);
return;
}
_listbox.Items.Add(text);
}
cant find a way to fix it, is my code correct?
btw im not a native speaker so bear with my understanding problems :D
_buffer member variable is being used for all send/receive/accept operations. This can cause serious problems, try using separate member buffer variable for each operation.
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?
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;
}
}