i have a TCP Chat Server code sample like this, it creates multiple threads correctly, but it doesn't send the message to all threads. I want the message to be sent accross all threads, like a group chat. Can you help me?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
class NewClient
{
public Socket newServerSocket;
public NewClient(Socket client)
{
this.newServerSocket = client;
}
public void speakWithClient()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint clientep = (IPEndPoint) newServerSocket.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}",
clientep.Address, clientep.Port);
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newServerSocket.Send(data, data.Length,SocketFlags.None);
Right here, it sends the given message back to the client, but it doesn't send the message to all threads.
while (true)
{
data = new byte[1024];
recv = newServerSocket.Receive(data);
if (recv == 0)
break;
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
newServerSocket.Send(data, recv, SocketFlags.None);
}
Console.WriteLine("Disconnected from {0}",
clientep.Address);
newServerSocket.Close();
}
}
class SimpleTcpSrvr
{
public static void Main()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any,9060);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
newsock.Bind(ipep);
newsock.Listen(10);
Console.WriteLine("Waiting for a client...");
while (true)
{
Socket client = newsock.Accept();
NewClient threadliclient = new NewClient(client);
Thread newthread = new Thread(new ThreadStart(threadliclient.speakWithClient));
newthread.Start();
}
}
}
It's been a while since I've done any socket programming, but... don't you need to keep a list of your client sockets and loop through them every time you receive a message?
public static List<Socket> Clients = new List<Socket>();
while (true)
{
Socket client = newsock.Accept();
Clients.Add(client);
NewClient threadliclient = new NewClient(client);
Thread newthread = new Thread(new ThreadStart(threadliclient.speakWithClient));
newthread.Start();
}
public void speakWithClient()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint clientep = (IPEndPoint) newServerSocket.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}", clientep.Address, clientep.Port);
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newServerSocket.Send(data, data.Length,SocketFlags.None);
while (true)
{
data = new byte[1024];
recv = newServerSocket.Receive(data);
if (recv == 0)
break;
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
foreach (Socket client in SimpleTcpSrvr.Clients)
{
client.Send(data, recv, SocketFlags.None);
}
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Hi I written simple client socket application, where client send some string to server, server receives it and convert the string to upper case and send back to client. Client print the message from server to console. But When I ran the application, I am getting 'input string was not in correct format' error while converting the bytes received from server. Since I am new to C# programming, Can some one help me to understand why this error coming, and how to resolve it?
Server.cs
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Server
{
public class ServerSocket
{
private int port;
private Socket serverSocket;
public ServerSocket(int port)
{
this.port = port;
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
/* Associates a Socket with a local endpoint. */
serverSocket.Bind(serverEndPoint);
/*Places a Socket in a listening state.
* The maximum length of the pending connections queue is 100
*/
serverSocket.Listen(100);
}
public void start()
{
Console.WriteLine("Starting the Server");
/* Accept Connection Requests */
Socket accepted = serverSocket.Accept();
/* Get the size of the send buffer of the Socket. */
int bufferSize = accepted.SendBufferSize;
byte[] buffer = new byte[bufferSize];
/* Receives data from a bound Socket into a receive buffer. It return the number of bytes received. */
int bytesRead = accepted.Receive(buffer);
byte[] formatted = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
{
formatted[i] = buffer[i];
}
String receivedData = Encoding.UTF8.GetString(formatted);
Console.WriteLine("Received Data " + receivedData);
String response = receivedData.ToUpper();
byte[] resp = Encoding.UTF8.GetBytes(response);
accepted.Send(resp, 0, resp.Length, 0);
Console.WriteLine("Press some key to close");
Console.Read();
}
}
class Server
{
static void Main(string[] args)
{
ServerSocket server = new ServerSocket(1234);
server.start();
}
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
namespace client
{
public class ClientSocket{
private Socket clientSocket;
private int port;
public ClientSocket(int port)
{
this.port = port;
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void start()
{
Console.WriteLine("Starting client socket");
try
{
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
clientSocket.Connect(serverEndPoint);
Console.WriteLine("Enter some data to send to server");
String data = Console.ReadLine();
byte[] bytes = Encoding.UTF8.GetBytes(data);
clientSocket.Send(bytes);
Console.WriteLine("Closing connection");
int receiveBufferSize = clientSocket.ReceiveBufferSize;
byte[] buffer = new byte[receiveBufferSize];
int receivedBytes = clientSocket.Receive(buffer);
byte[] receivedData = new byte[receivedBytes];
for(int i=0; i < receivedBytes; i++)
{
receivedData[i] = buffer[i];
Console.WriteLine(receivedData[i]);
}
String received = Encoding.UTF8.GetString(receivedData);
Console.WriteLine("Response : {}", received);
Console.WriteLine("Press Enter to close");
Console.Read();
clientSocket.Close();
}
catch (Exception e)
{
Console.WriteLine("Error while connectiong to server {}", e.Message );
}
}
}
class Client
{
static void Main(string[] args)
{
ClientSocket clientSocket = new ClientSocket(1234);
clientSocket.start();
}
}
}
The line:
Console.WriteLine("Response : {}", received);
should be:
Console.WriteLine("Response : {0}", received);
I want to write a programm where multiple clients can join on a server. For now the clients are only able to ask for the servertime, which works perfectly fine, as long as the client and the server are on the same pc. I'm pretty sure that I have to change the EndPoint in the Connect() Method of the client, but I don't know what i should change it to.
Please help me to find a solution for this.
I have this code on my server:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Multiple_Clients
{
class Program
{
private static int port = 4567;
private static byte[] _buffer = new byte[1024];
private static List<Socket> _clientSockets = new List<Socket>();
private static Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void Main(string[] args)
{
Console.Title = "Server";
setupServer();
Console.ReadLine();
}
private static void setupServer()
{
Console.WriteLine("Setting up server...");
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, port));
_serverSocket.Listen(500);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null);
}
private static void acceptCallback(IAsyncResult AR)
{
Socket socket = _serverSocket.EndAccept(AR);
_clientSockets.Add(socket);
Console.WriteLine("Client connected");
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(acceptCallback), null);
}
private static void receiveCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
Console.WriteLine("Text received: " + text);
string response = string.Empty;
if (text.ToLower() != "get time")
{
response = "Invalid Request";
}
else
{
response = DateTime.Now.ToLongTimeString();
}
byte[] data = Encoding.ASCII.GetBytes(response);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(sendCallback), socket);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), socket);
}
private static void sendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
}
}
And this on my client
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace Multiple_Clients
{
class Program
{
private static int port = 4567;
private static Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void Main(string[] args)
{
Console.Title = "Client";
connect();
sendLoop();
Console.ReadLine();
}
private static void connect()
{
int attempts = 0;
while(!_clientSocket.Connected)
{
try
{
attempts++;
_clientSocket.Connect(IPAddress.Loopback, port);
}
catch(SocketException)
{
Console.Clear();
Console.WriteLine("Connection attempts: " + attempts.ToString());
}
}
Console.Clear();
Console.WriteLine("Connected");
}
private static void sendLoop()
{
while (true)
{
Console.Write("Enter a request:");
string req = Console.ReadLine();
byte[] buffer = Encoding.ASCII.GetBytes(req);
_clientSocket.Send(buffer);
byte[] receivedBuf = new byte[1024];
int rec = _clientSocket.Receive(receivedBuf);
byte[] data = new byte[rec];
Array.Copy(receivedBuf, data, rec);
Console.WriteLine("Received: " + Encoding.ASCII.GetString(data));
}
}
}
}
Any suggestions on how to improve this question are welcome.
Thank you very much for helping me!
Your client allways connect to IPAddress.Loopback ... in fact the local IP Address 127.0.0.1. Exchange IPAddress.Loopback to the real IPAdress of your server, e. g. IPAddress.Parse("192.168.?.?") ...!
I'm trying to transfer some data between android client and .net server.
I used sockets. the client sockets is connected while in the server I get no response.
can anyone please review this code and help me? I'm kind of lost.
my client code:
Socket socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
try
{
socket1.Connect(IPAddress.Parse(string_ip), 8080);
if (socket1.Connected)
{
Log("connected");
NetworkStream networkStream1 = new NetworkStream(socket1);
byte[] sendData = new byte[1024];
byte[] recievedData = new byte[1024];
string message = "alon aviv";
sendData = Encoding.UTF8.GetBytes(message);
networkStream1.Write(sendData, 0, sendData.Length);
}
else
{ Log("not connected"); }
}
my server code:
Socket socket1 = new Socket(SocketType.Stream, ProtocolType.IP);
System.Net.IPEndPoint ipEnd = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(string_ip), 8080);
socket1.Bind(ipEnd);
socket1.Listen(1);
socket1.Accept();
if (socket1.Connected)
{
UpdateLogText("socket connected");
NetworkStream networkStream1 = new NetworkStream(socket1);
byte[] recievedData = new byte[1024];
networkStream1.Read(recievedData, 0, recievedData.Length);
string message_recieved = Encoding.ASCII.GetString(recievedData);
UpdateLogText(message_recieved);
}
I also tested your code and it was not working at my side as well. I made some adjustments which do work. Please try:
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
byte[] bytes = new byte[1024];
Socket socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
try
{
socket1.Connect(IPAddress.Parse("127.0.0.1"), 8080);
if (socket1.Connected)
{
Console.WriteLine("Connected");
// Encode the data string into a byte array.
byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
// Send the data through the socket.
int bytesSent = socket1.Send(msg);
// Receive the response from the remote device.
int bytesRec = socket1.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
// Release the socket.
socket1.Shutdown(SocketShutdown.Both);
socket1.Close();
}
else
{
Console.WriteLine("not connected");
}
Console.ReadLine();
}
catch (Exception e)
{
}
}
}
}
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
public static string data = null;
static void Main(string[] args)
{
byte[] bytes = new Byte[1024];
Socket socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
System.Net.IPEndPoint ipEnd = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 8080);
// Bind the socket to the local endpoint and
// listen for incoming connections.
try
{
socket1.Bind(ipEnd);
socket1.Listen(10);
// Start listening for connections.
while (true)
{
Console.WriteLine("Waiting for a connection...");
// Program is suspended while waiting for an incoming connection.
Socket handler = socket1.Accept();
data = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
// Show the data on the console.
Console.WriteLine("Text received : {0}", data);
// Echo the data back to the client.
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.ReadLine();
}
}
}
OK, so I am not very good at programming in general, but I want to try my hand at using sockets. To start I watched a Youtube video which I followed step by step, I got the finished product working 100% to the guides however I wish to modify it in order for the server to be able to send a message to all connected clients.
Here is the youtube video: Youtube Video - Sockets
So this is the code for the server class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace Server
{
class Program
{
private static byte[] buffer = new byte[1024];
public static Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static List<Socket> clientSockets = new List<Socket>();
static void Main(string[] args)
{
Console.Title = "Server, " + clientSockets.Count.ToString() + " clients are connected";
SetupServer();
Console.ReadLine();
}
public static void SetupServer()
{
Console.WriteLine("Setting up server...");
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
_serverSocket.Listen(5);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
public static void AcceptCallback(IAsyncResult AR)
{
Socket socket = _serverSocket.EndAccept(AR);
clientSockets.Add(socket);
Console.WriteLine("Client Connected");
Console.Title = "Server, " + clientSockets.Count.ToString() + " clients are connected";
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private static void RecieveCallBack(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
string response = string.Empty;
if (s.ToLower() == "get time")
{
response = DateTime.Now.ToLongTimeString();
}
else
{
response = "Invalid Request";
}
byte[] data = Encoding.ASCII.GetBytes(response);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(sendCallback), socket);
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), socket);
}
private static void sendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
}
}
I had a pretty pathetic attempt at what I wanted to do:
private static void RecieveCallBack(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
foreach(Socket s1 in clientSockets){
string response = string.Empty;
if (s.ToLower() == "get time")
{
response = DateTime.Now.ToLongTimeString();
}
else
{
response = "Invalid Request";
}
byte[] data = Encoding.ASCII.GetBytes(response);
s1.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(sendCallback), s1);
s1.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), s1);
}
}
wasn't really expecting it too work, but I gave it a go.
Another secondary question:
Is this the line of code which determines what IP and Port the server will be listening on?
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
Used the same code, had the same problem.
It is not working because the client console is stuck in readLine(), so it is not receiving responses. After you send a command don't call Console.ReadLine again.
To loop trough all clients and send a message:
private static void sentToAll(string s)
{
foreach (Socket socket in clientSockets)
{
byte[] data = Encoding.ASCII.GetBytes(s);
socket.Send(data);
}
}
private static IPEndPoint localEndPoint;
public static String IpAddress = "10.0.0.13";
public static int port = 3000;
localEndPoint = new IPEndPoint(IPAddress.Parse(IpAddress), port);
_serverSocket.Bind(localEndPoint);
I have been trying to get this asynchronous UDP server working for the past two days and am banging my head against the wall now.
I am currently running into getting a SocketException for 10057 when I am trying to get RemoteEndPoint from the Socket in the ReceiveCallback.
When looking with the debugger socket is filled, state is filled. LocalEndPoint is normally set to {0.0.0.0:53}, yet RemoteEndPoint says a SocketException was thrown. And I do not understand what I am missing in my set up. Any helps, tips, guidance welcome.
namespace UDPServer
{
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class StateObject
{
// Client socket
public Socket socket = null;
// Size of the receive buffer
public const int BufferSize = 1024;
// Receive buffer
public byte[] buffer = new byte[BufferSize];
}
public class ServerAsync
{
private static int portNumber = 53;
public static ManualResetEvent WaitEvent = new ManualResetEvent(false);
public static void StartListening()
{
// Data buffer
byte[] bytes = new byte[1024];
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, portNumber);
EndPoint client = new IPEndPoint(IPAddress.Any, 0);
socket.Bind(localEndPoint);
Console.WriteLine("Listening for UDP queries on port 53");
while (true)
{
// Set event to non-signaled state.
WaitEvent.Reset();
Console.WriteLine("Waiting for a connection...");
StateObject state = new StateObject();
state.socket = socket;
socket.BeginReceiveFrom(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, ref client, new AsyncCallback(ReceiveCallback), state);
// Wait until a connection is made before continuing.
WaitEvent.WaitOne();
}
}
public static void ReceiveCallback(IAsyncResult ar)
{
// Signal main thread to continue.
WaitEvent.Set();
int bytesRead = 0;
try
{
if (ar.IsCompleted)
{
StateObject state = (StateObject)ar.AsyncState;
Socket socket = state.socket;
IPEndPoint sender = (IPEndPoint)socket.RemoteEndPoint;
EndPoint remoteEndPoint = (EndPoint)sender;
bytesRead = socket.EndReceiveFrom(ar, ref remoteEndPoint);
if (bytesRead > 0)
{
Console.WriteLine("Received {0} bytes from {1}:{2}: {3}", bytesRead, sender.Address.ToString(), sender.Port.ToString(), BitConverter.ToString(state.buffer));
socket.BeginReceiveFrom(state.buffer, 0, StateObject.BufferSize, 0, ref remoteEndPoint, new AsyncCallback(ReceiveCallback), state);
}
}
}
catch (SocketException se)
{
Console.WriteLine("SocketException: " + se.ErrorCode + ": " + se.Message);
}
catch (ObjectDisposedException ode)
{
Console.WriteLine("Socket closed: " + ode.Message);
}
}
public static void Main(string[] args)
{
Console.WriteLine("Server starting up...");
StartListening();
}
}
}
Why is your main thread looping and reading from the port when the EndCallback is also starting a new read? It looks to me like two threads will be trying to read from the port simultaneously, using the same StateObject.
Also, your receive callback is using the AsyncResult's buffer to start a new read operation. Do you know what the socket does with the AsyncResult object after you return? Can you be sure it doesn't dispose it? You may need to create a new AsyncResult for each read request so that they remain truly independent.