i have these code for a server and client program. client program sends a value to server and server reads it. but here after first message, server shuts down.
i want it to be listerning until the full application shuts down. so after 1 connection closes, it will wait for next connection and so on.
internal static async Task ServerHandler()
{
Console.Writeline("starting server...");
IPAddress b = IPAddress.Any;
TcpListener Server = new TcpListener(b, 5550);
Server.Start();
Console.Writeline("Server Started Sucessfully!");
Console.Writeline("Waiting for Connection...");
TcpClient Client = Server.AcceptTcpClient();
string clientIPAddress = "Connected! => " + IPAddress.Parse(((IPEndPoint)Client.Client.RemoteEndPoint).Address.ToString());
Console.Writeline(clientIPAddress);
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
try
{
Stream MessageStream = Client.GetStream();
bytesRead = MessageStream.Read(message, 0, 4096);
ASCIIEncoding encoder = new ASCIIEncoding();
string recivedMessage = encoder.GetString(message, 0, bytesRead);
Console.Writeline(recivedMessage);
}
catch (Exception e)
{
Console.WriteLine(e);
}
Client.Close();
Server.Stop();
}
}
Related
So I am working on creating my own proxy server for my game server.
Whats happening so far is that I try to connect to my Terraria server and it says
Connecting..
Then I start my server application which accepts incoming requests on that specific IP & port and it prompts a MessageBox saying"Connected" and then the game goes from "Connecting..." to "Connecting to server..." but it gets stuck there, this is most likely because I am not redirecting the traffic from my proxy server to my server.. Right?
I've been trying to .Write() to the stream but I think I am writing to the wrong stream, do I write to the stream that accepts connections or do I create a new stream for outgoing traffic?
public partial class MainWindow : Window
{
public static IPAddress remoteAddress = IPAddress.Parse("127.0.0.1");
public TcpListener remoteServer = new TcpListener(remoteAddress, 7777);
public TcpClient client = default(TcpClient);
public TcpClient RemoteClient = new TcpClient("terraria.novux.ru", 7777);
public MainWindow()
{
InitializeComponent();
}
private void BtnListen_OnClick(object sender, RoutedEventArgs e)
{
if (StartServer())
{
client = remoteServer.AcceptTcpClient();
MessageBox.Show("Connected");
var receivedBuffer = new byte[1024];
//Should I write to this one instead?
var clientStream = client.GetStream();
var stream = RemoteClient.GetStream();
while (client.Connected)
if (client.Connected)
if (client.ReceiveBufferSize > 0)
{
receivedBuffer = new byte[1024];
stream.Write(receivedBuffer, 0, receivedBuffer.Length);
}
}
}
private bool StartServer()
{
try
{
remoteServer.Start();
MessageBox.Show("Server Started...");
return true;
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString());
throw;
}
}
}
A simplified implementation could look like this.
public class Program
{
public static void Main(string[] args)
{
StartTcpListener("localhost", 9000);
}
private static byte[] SendReceiveRemoteServer(string host, int port, byte[] data)
{
try
{
// Create a TcpClient.
// Note, for this client to work you need to have a TcpServer
// connected to the same address as specified by the server, port
// combination.
var client = new TcpClient(host, port);
// Get a client stream for reading and writing.
// Stream stream = client.GetStream();
var stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent to server: {0}", Encoding.ASCII.GetString(data));
// Receive the TcpServer.response.
// Read the first batch of the TcpServer response bytes.
var bytes = new byte[256];
var allBytes = new List<byte>();
var i = stream.Read(bytes, 0, bytes.Length);
// Loop to receive all the data sent by the client.
while (i != 0)
{
allBytes.AddRange(bytes);
bytes = new Byte[256];
i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
}
Console.WriteLine("Received from server: {0}", Encoding.ASCII.GetString(data));
// Close everything.
stream.Close();
client.Close();
return allBytes.ToArray();
}
catch (ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
Console.WriteLine("\n Press Enter to continue...");
return new byte[0];
}
private static void StartTcpListener(string host, int port)
{
TcpListener server = null;
try
{
var ipHostInfo = Dns.GetHostEntry(host);
var ipAddress = ipHostInfo.AddressList[0];
// TcpListener server = new TcpListener(port);
server = new TcpListener(ipAddress, port);
// Start listening for client requests.
server.Start();
// Enter the listening loop.
while (true)
{
Console.WriteLine("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
var client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
var stream = client.GetStream();
// Buffer for reading data
var bytes = new Byte[256];
var allBytes = new List<byte>();
var i = stream.Read(bytes, 0, bytes.Length);
// Loop to receive all the data sent by the client.
while (i != 0)
{
allBytes.AddRange(bytes);
bytes = new Byte[256];
i = stream.DataAvailable ? stream.Read(bytes, 0, bytes.Length) : 0;
}
if (allBytes.Count > 0)
{
Console.WriteLine("Received from client: {0}", Encoding.ASCII.GetString(allBytes.ToArray()));
var received = SendReceiveRemoteServer("localhost", 11000, allBytes.ToArray());
// Send back a response.
stream.Write(received, 0, received.Length);
Console.WriteLine("Sent to client: {0}", Encoding.ASCII.GetString(received));
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
}
}
Although improvements should be made:
make it async
make it work with multiple TcpClients at the same time
All i want to do is send message to client from server. I try a lot of tutorial etc. but still can't send message from server to client.
Send from client to server is simple and have it in code. When client Send "HI" to server i want to respond Hi to client. But dunno what should i add to my code. Can someone help me with that? Please don't do it like duplicate i know there is a lot of similar topic but can't find solution.
Server code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
IPAddress ip = Dns.GetHostEntry("localhost").AddressList[0];
TcpListener server = new TcpListener(ip, Convert.ToInt32(8555));
TcpClient client = default(TcpClient);
try
{
server.Start();
Console.WriteLine("Server started...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
};
while (true)
{
client = server.AcceptTcpClient();
byte[] receivetBuffer = new byte[100];
NetworkStream stream = client.GetStream();
stream.Read(receivetBuffer, 0, receivetBuffer.Length);
StringBuilder msg = new StringBuilder();
foreach(byte b in receivetBuffer)
{
if (b.Equals(59))
{
break;
}
else
{
msg.Append(Convert.ToChar(b).ToString());
}
}
////Resive message :
if (msg.ToString() =="HI")
{
///#EDIT 1
///// HERE Is SENDING MESSAGE TO CLIENT//////////
int byteCount = Encoding.ASCII.GetByteCount("You said HI" + 1);
byte[] sendData = new byte[byteCount];
sendData = Encoding.ASCII.GetBytes("You said HI" + ";");
stream.Write(sendData, 0, sendData.Length);
}
}
Client code:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
try
{
string serverIP = "localhost";
int port = Convert.ToInt32(8555);
TcpClient client = new TcpClient(serverIP, port);
int byteCount = Encoding.ASCII.GetByteCount("HI"+ 1);
byte[] sendData = new byte[byteCount];
sendData = Encoding.ASCII.GetBytes("HI" + ";");
NetworkStream stream = client.GetStream();
stream.Write(sendData, 0, sendData.Length);
///////////////////////////////HERE I WANT A read message from server/
/////////////////////////////////////////////////////////////////////
stream.Close();
client.Close();
}
catch(Exception ex)
{
ex.ToString();
}
}
Try this Here is my version of client and server ,feel free to ask if any reference problem ,the client wait for server to (online) then if server is online connect with it.
Method to Connect with Server
private void Connectwithserver(ref TcpClient client)
{
try
{
//this is server ip and server listen port
server = new TcpClient("192.168.100.7", 8080);
}
catch (SocketException ex)
{
//exceptionsobj.WriteException(ex);
Thread.Sleep(TimeSpan.FromSeconds(10));
RunBoTClient();
}
}
byte[] data = new byte[1024];
string stringData;
TcpClient client;
private void RunClient()
{
NetworkStream ns;
Connectwithserver(ref client);
while (true)
{
ns = client.GetStream();
//old
// ns.ReadTimeout = 50000;
//old
ns.ReadTimeout = 50000;
ns.WriteTimeout = 50000;
int recv = default(int);
try
{
recv = ns.Read(data, 0, data.Length);
}
catch (Exception ex)
{
//exceptionsobj.WriteException(ex);
Thread.Sleep(TimeSpan.FromSeconds(10));
//try to reconnect if server not respond
RunClient();
}
//READ SERVER RESPONSE/MESSAGE
stringData = Encoding.ASCII.GetString(data, 0, recv);
}
}
Server
IPAddress localAdd = IPAddress.Parse(SERVER_IP);
TcpListener listener = new TcpListener(localAdd, PORT_NO);
Console.WriteLine("Listening...");
listener.Start();
while (true)
{
//---incoming client connected---
TcpClient client = listener.AcceptTcpClient();
//---get the incoming data through a network stream---
NetworkStream nwStream = client.GetStream();
byte[] buffer = new byte[client.ReceiveBufferSize];
//---read incoming stream---
int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);
//---convert the data received into a string---
string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received : " + dataReceived);
//IF YOU WANT TO WRITE BACK TO CLIENT USE
string yourmessage = console.ReadLine();
Byte[] sendBytes = Encoding.ASCII.GetBytes(yourmessage);
//---write back the text to the client---
Console.WriteLine("Sending back : " + yourmessage );
nwStream.Write(sendBytes, 0, sendBytes.Length);
client.Close();
}
listener.Stop();
I have a sever that allows me to connect several clients receive a message from client and send every client a message when it connects.
What I'm trying to do is send a message from client to another so all the server is supposed to do is get the message from first client and send to another. How can I do that?
This is the code of the server
class Server
{
private TcpListener tcpListener; private Thread listenThread;
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch (Exception ex)
{
//a socket error has occured
Console.WriteLine(ex.Message);
}
if (bytesRead == 0)
{
//the client has disconnected from the server
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine(encoder.GetString(message, 0, bytesRead));
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
tcpClient.Close();
}
static void Main(string[] args)
{
new Server();
}
}
and the client
{
TcpClient client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
//message has successfully been received
byte[] message = new byte[4096];
int bytesRead;
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine(encoder.GetString(message, 0, bytesRead));
Console.ReadLine();
}
You have to hold the incoming TcpClient objects in memory so that you can send to them later.
Something like:
List<TcpClient> connectedClients = new List<TcpClient>();
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
connectedClients.Add(client);
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
Then you can get the client out of the list (or just send to the whole list) normally. You may want to encapsulate the TcpClient into a full-fledged "Client" object so you can keep track of what they send/receive and also send messages to specific clients.
I have a GUI with 2 buttons and a text box. Button1 starts a server and has it listen for clients. Button 2 sends a connection request to the server and starts to listen for anything the server will send to the client (responses). Although w/ my current code when the Server sends the reply and I try to write it to a text box the whole system hangs.
Code as seen below:
Server Class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Client!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
tcpClient.Close();
}
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 3000);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
}
GUI class:
private void buttonServerStart_Click(object sender, EventArgs e)
{
Server Myserver = new Server();
}
//Greet the Server and listen for response...
private void EthStartB_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
byte[] message = new byte[4096];
int bytesRead;
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);
client.Connect(serverEndPoint);
NetworkStream clientStream = client.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
//start listening
this.ClientListener.Start();
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
tb_recieved.Clear();
tb_recieved.Text=encoder.GetString(message,0,bytesRead);
}
}
TcpListener ClientListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
private void EthEndB_Click(object sender, EventArgs e)
{
Form3 frmT = new Form3();
frmT.Show();
}
}
The issue is when private void EthStartB_Click(object sender, EventArgs e) calls the code line of tb_recieved.Text=encoder.GetString(message,0,bytesRead);
The program hangs because you have a while(true) loop in EthStartB_Click which runs on UI thread. clientStream.Read call will block UI thread.
Move the receive logic on a new thread and set the textbox content using Control.Invoke or Dipatcher.Invoke depending on whether you are on WinForms or WPF - and do that only if you do have some content in the message to be written to textbox.
There also another issue, since you have the tcpClient.Close() outside the while loop on the server, neither client nor server will disconnect. Both will block on their respective stream.Read calls.
Since you are running both client and server on same machine, that TcpListener ClientListener is not required and will not play well with the server already listening on the same port.
I created a client and server that connect to each other. The server is capable of sending the message a client sent back to the client (after processing)... however... if there are two clients connected, it only sends the message back to the client that sent the message in the first place (lol...)
How would i fix this so that it sends a message from any client to every client?
I used the example below as a starting point to get a connection between the client and server:
client server communication
when i try the following my program freezes up:
SERVER:
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch (Exception ex)
{
Debug.Print(ex.Message);
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
foreach (TcpClient c in ListOfClients)
{
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
clientStream.Write(message, 0, message.Length);
}
CLIENT:
private void boxChatArea_KeyPress(object sender, KeyPressEventArgs e)
{
char[] contentForServer = null;
boxChatArea.MaxLength = 4000;
if (e.KeyChar == (char)Keys.Enter)
{
client = new TcpClient();
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), MainWindow.port);
client.Connect(serverEndPoint);
clientStream = client.GetStream();
contentForServer = boxChatArea.Text.ToCharArray();
byte[] bytesToSend = System.Text.Encoding.ASCII.GetBytes(contentForServer);
clientStream.Write(bytesToSend, 0, bytesToSend.Length);
clientStream.Flush();
boxChatArea.Text = null;
StartListening();
}
}
public void StartListening()
{
HandleServerComm(client);
}
private void HandleServerComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
bytesRead = 0;
try
{
//FREEZES HERE - it doesn't freeze here without the loop that we added within the server...
bytesRead = clientStream.Read(message, 0, 4096);
}
catch (Exception ex)
{
Debug.Print(ex.Message);
//break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
}
if (bytesRead != 0)
{
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
string text = (encoder.GetString(message, 0, message.Length));
if (enterCount >= 1)
{
displayBoxChatArea.AppendText(Environment.NewLine);
displayBoxChatArea.AppendText(text);
//displayBoxChatArea.Text = text;
Application.DoEvents();
}
else
{
displayBoxChatArea.Text = text;
Application.DoEvents();
}
}
enterCount++;
tcpClient.Close();
}
You should take a list of connected clients.
Try something like this:
List<TcpClient> clients = new List<TcpClient>();
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
if(!clients.Contains(clients))
clients.Add(client);
}
}
EDITED after user comments:
You did your sending function wrong: you must first get just the message from one client, then send to everyone.
clientStream = tcpClient.GetStream(); // Not in foreach loop !!
// ...
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
foreach(TcpClient client in clients)
{
// Send message to client
st = client.GetStream();
st.Write(message, 0, message.Length);
}