so made client-server-client tcp/ip app in c# that are supposed to communicate between 2 computers that are in different network.
I have few problems , first of them my server wont start on my public ip sayings its not valid in this context. Second is that I need to press send button twice before it sends data to server ,and then server 2 variations of data, one in bytes, other in char how its supposed to be. And third is how to make clients trying to receive data whole time. Should I have connection between clients have open whole time? I tried using timers to check if there is data to be received from the server.
Server code
static void Main(string[] args)
{
TcpListener server = new TcpListener(IPAddress.Parse("192.168.0.13"), 8080);
TcpClient client = default(TcpClient);
TcpClient client2 = default(TcpClient)
try
{
server.Start();
Console.WriteLine("Server started...");
}
catch(Exception ex)
{
Console.WriteLine("Server failed to start... {0}",ex.ToString());
Console.Read();
}
while (true)
{
client = server.AcceptTcpClient(); /
byte[] receivedBuffer = new byte[1000];
NetworkStream stream = client.GetStream();
stream.Read(receivedBuffer,0,receivedBuffer.Length);
StringBuilder message = new StringBuilder(); foreach (byte b in receivedBuffer)
{
if (b.Equals(126)
) //proveramo d {
break;
}
else
{
message.Append(Convert.ToChar(b).ToString()); }
}
client2 = server.AcceptTcpClient();
byte[] receivedBuffer2 = new byte[1000];
NetworkStream stream2 = client2.GetStream();
stream2.Read(receivedBuffer2, 0, receivedBuffer2.Length);
StringBuilder message2 = new StringBuilder();
foreach (byte g in receivedBuffer2)
{
if (g.Equals(126))
{
break;
}
else
{
message2.Append(g);
}
}
stream2.Write(receivedBuffer, 0, receivedBuffer.Length);
stream.Write(receivedBuffer2,0,receivedBuffer2.Length);
Console.WriteLine(message2.ToString());
Console.WriteLine(message.ToString());
}
Client code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
private int port = 8080;
private void submit_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient("192.168.0.13",port);
TcpListener listener = new TcpListener(IPAddress.Parse("192.168.0.13"), port);
long byteCount = Encoding.ASCII.GetByteCount(messagebox_TB.Text + 1); byte[] sentDataBytes = new byte[byteCount];
sentDataBytes = Encoding.ASCII.GetBytes(messagebox_TB.Text + "~");
NetworkStream stream = client.GetStream();
stream.Write(sentDataBytes,0,sentDataBytes.Length);
stream.Close();
client.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
long a = 0;
try
{
TcpClient client = new TcpClient("192.168.0.13", port);
TcpListener listener = new TcpListener(IPAddress.Parse("192.168.0.13"), port);
NetworkStream stream = client.GetStream();
byte[] receviedBytes = new byte[100];
stream.Read(receviedBytes, 0, receviedBytes.Length);
StringBuilder
message = new StringBuilder();
foreach (byte b in receviedBytes) {
if (b.Equals(126)
) //proveramo {
break;
}
else
{
message.Append(Convert.ToChar(b).ToString()); }
}
textBox1.Text = message.ToString();
client.Close();
stream.Close();
}
catch
{
a++;
}
}
}
Related
So I am playing around with the Tcp protocol in C# and figured I would connect to my server.
When I connect to my server it notifies me just fine. but then I go to check the ReceivedBufferSize and it's this receivedBuffer={byte[65536]}
When in reality it only gives back a few bytes.
Why is this happening?
Sending this back to my client doesn't do anything either so I removed that part.
I figured it's because the packet is so big.
This part right here
byte[] receivedBuffer = new byte[client.ReceiveBufferSize];
returns receivedBuffer={byte[65536]}
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 MainWindow()
{
InitializeComponent();
}
private void BtnListen_OnClick(object sender, RoutedEventArgs e)
{
if (StartServer())
{
client = remoteServer.AcceptTcpClient();
MessageBox.Show("Connected");
byte[] receivedBuffer = new byte[client.ReceiveBufferSize];
NetworkStream clientStream = client.GetStream();
while (client.Connected)
{
if (client.Connected)
{
if (client.ReceiveBufferSize > 0)
{
receivedBuffer = new byte[100];
clientStream.Read(receivedBuffer, 0, receivedBuffer.Length);
}
}
}
}
}
private bool StartServer()
{
try
{
remoteServer.Start();
MessageBox.Show("Server Started...");
return true;
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString());
throw;
}
}
}
As you can see here, it's only 15 bytes
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
This is my first TCP listener program,
I could receive, parse and display data successfully from another PC.
But can you please check why this listener is not receiving another data ?
I want to update it everytime time when a client sends data. But its not updating once received data.
Here is my code:
public partial class FeederControlMonitor : Form
{
public string Status = string.Empty;
public Thread T = null;
public FeederControlMonitor()
{
InitializeComponent();
}
private void FeederControlMonitor_Load(object sender, EventArgs e)
{
label1.Text = "Server is Running...";
ThreadStart Ts = new ThreadStart(StartReceiving);
T = new Thread(Ts);
T.Start();
}
public void StartReceiving()
{
ReceiveTCP(9100);
}
public void ReceiveTCP(int portN)
{
TcpListener Listener = null;
try
{
Listener = new TcpListener(IPAddress.Any, portN);
Listener.Start();
}
catch (Exception ex)
{
File.WriteAllText(#"C:\\Drive\\ex.txt", ex.Message);
Console.WriteLine(ex.Message);
}
try
{
Socket client = Listener.AcceptSocket();
byte[] data = new byte[10000];
int size = client.Receive(data);
while (true)
{
client.Close();
ParseData(System.Text.Encoding.Default.GetString(data));
}
Listener.Stop();
}
catch (Exception ex)
{
File.WriteAllText(#"C:\\Drive\\ex.txt", ex.Message);
}
}
public void ParseData(string data)
{
var useFulData = data.Substring(data.IndexOf("F1")).Replace(" ", "");
useFulData = useFulData.Remove(useFulData.IndexOf("<ETX>"));
string[] delimeters = { "<DEL>", "<ESC>" };
var listOfValues = useFulData.Split(delimeters, StringSplitOptions.None).ToList();
int pos = 0;
for (int i = 1; i < listOfValues.Count; i += 2, pos++)
{
listOfValues[pos] = listOfValues[i];
}
listOfValues.RemoveRange(pos, listOfValues.Count - pos);
txtTubeName.Text = listOfValues[0];
txtCID.Text = listOfValues[1];
txtLocation.Text = listOfValues[2];
txtGender.Text = listOfValues[3];
txtAge.Text = listOfValues[4];
}
private void btnExit_Click(object sender, EventArgs e)
{
T.Abort();
this.Close();
}
}
Thanks in advance.
To much to explain where are errors. Here is simple multithread TcpServer.
// Initialize listener.
IPAddress address = new IPAddress(new byte[] { 127, 0, 0, 1 });
TcpClient client;
// Bind to address and port.
TcpListener listener = new TcpListener(address, 12345);
// Start listener.
listener.Start();
// In endless cycle accepting incoming connections.
// Actually here must be something like while(_keepWork)
// and on some button code to make _keepWork = false to
// stop listening.
while (true)
{
client = listener.AcceptTcpClient();
// When client connected, starting BgWorker
// use "using" statement to automatically free objects after work.
using (BackgroundWorker bgWorker = new BackgroundWorker())
{
// EventHandler.
bgWorker.DoWork += BgWorker_DoWork;
// Past client as argument.
bgWorker.RunWorkerAsync(client);
}
}
And method to handle connection (Edit: with read data part):
private static void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
// Get argument as TcpClient.
TcpClient client = e.Argument as TcpClient;
// Get stream from client.
NetworkStream netStream = client.GetStream();
// Input buffer to read from stream.
int inBuffSize = 1024;
byte[] inBuff = new byte[inBuffSize];
// Temporary buffer.
byte[] tempBuff;
// Result data recieved from client.
List<byte> data = new List<byte>();
// Read bytes from client into inputbuffer
int dataSize = netStream.Read(inBuff, 0, inBuffSize);
// If data recieved add to result.
while (dataSize > 0)
{
// Create new buffer.
tempBuff = new byte[dataSize];
// Copy data from inputBuffer to tempBuffer.
Array.Copy(inBuff, tempBuff, dataSize);
// Add to result.
data.AddRange(tempBuff);
// Read once more to check if any data still could be recieved.
dataSize = netStream.Read(inBuff, 0, inBuffSize);
}
}
I have created server application to accept connection from clients. After client connected to server ... they can send data and receive data between each other , but when another client is connected ... the server can not send data to frist client connected .
I need help how to save connected client on this server ... and how to send data to specified client.
The server class is :
namespace WindowsApplication11
{
public partial class Form1 : Form
{
private TcpListener tcpListener;
private Thread listenThread;
public Form1()
{
InitializeComponent();
}
TcpListener myList;
private void Form1_Load(object sender, EventArgs e)
{
try
{
myList = new TcpListener(IPAddress.Any, 8001);
/* Start Listeneting at the specified port */
myList.Start();
while (true)
{
TcpClient client = myList.AcceptTcpClient();
saveclient(" Client " + client.Client.RemoteEndPoint.ToString());
// - receive msg from client -
byte[] bb = new byte[10000];
int kb = client.Client.Receive(bb);
string stringu = "";
for (int i = 0; i < kb; i++)
stringu += Convert.ToChar(bb[i]);
// - send msg to accepted client -
Byte[] datat = System.Text.Encoding.ASCII.GetBytes("nje-> " + stringu);
NetworkStream stream = client.GetStream();
stream.Write(datat, 0, datat.Length);
stream.Flush();
}
}
catch (Exception ea)
{
Console.WriteLine("Error..... " + ea.Message);
}
}
void saveclient(string idlidhje)
{
try
{
System.IO.StreamWriter stw = System.IO.File.AppendText("d:\\clients.txt");
string teksti = System.String.Format("{0:G}: {1}.", System.DateTime.Now, idlidhje);
stw.WriteLine(teksti + "\n");
stw.Close();
}
catch (Exception eks)
{
}
}
}
}
The client class is :
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IPAddress addr = IPAddress.Any;
byte[] data = new byte[1024];
string input, stringData;
TcpClient server;
try
{
server = new TcpClient("127.0.0.1", 8001);
// - send msg -
Byte[] datat = System.Text.Encoding.ASCII.GetBytes("Hello");
NetworkStream stream = server.GetStream();
stream.Write(datat, 0, datat.Length);
stream.Flush();
// - receive msg -
byte[] bb = new byte[10000];
int kb = server.Client.Receive(bb);
string stringu = "";
for (int i = 0; i < kb; i++)
stringu += Convert.ToChar(bb[i]);
}
catch (SocketException fd)
{
MessageBox.Show("Cannot connect " + fd.Message.ToString());
}
}
Robert answered to a similar question here on SO:
https://stackoverflow.com/a/15878306/17646
Basically you have to keep the connected clients in a list (your TcpClient object 'client' gets lost every time the while loop starts again) and you need threads or async methods to handle the different clients.
I am trying to learn TCP server/client interaction. I want to know how I would listen to a port all the time with GUI. Currently I am using this code:
private void Form1_Load(object sender, EventArgs e)
{
CreateServer();
}
void CreateServer()
{
TcpListener tcp = new TcpListener(25565);
tcp.Start();
Thread t = new Thread(() =>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((_) =>
{
Socket s = tcp.AcceptSocket();
console.Invoke((MethodInvoker)delegate { console.Text += "Connection esatblished: " + s.RemoteEndPoint + Environment.NewLine; });
byte[] b = new byte[100];
int k = s.Receive(b);
for (int i = 0; i < k; i++)
{
console.Text += Convert.ToChar(b[i]);
incoming += Convert.ToChar(b[i]);
}
MessageBox.Show(incoming);
console.Invoke((MethodInvoker)delegate { console.Text += incoming + Environment.NewLine; });
list.Invoke((MethodInvoker)delegate { list.Items.Add(incoming); });
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("\n"));
tcpClient.Close();
}, null);
}
});
t.IsBackground = true;
t.Start();
}
Any help would be much appreciateed.
Short answer - run TCP listener in the separate Thread/Task (TPL).
For full working solution you also have to implement dispatching of the any changes to UI form separate thread to main thread using special technique which is depends on Framework you are using, I mean WPF/WinForms/whatever.
Code below works for me fine. Read TODO section before.
TODO:
Add to form Textbox, ListBox, Button, make public:
public System.Windows.Forms.TextBox console;
public System.Windows.Forms.ListBox incommingMessages;
private System.Windows.Forms.Button sendSampleDataButton;
Entry point:
private static Form1 form;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
form = new Form1();
form.Load += OnFormLoad;
Application.Run(form);
}
private static void OnFormLoad(object sender, EventArgs e)
{
CreateServer();
}
Server:
private static void CreateServer()
{
var tcp = new TcpListener(IPAddress.Any, 25565);
tcp.Start();
var listeningThread = new Thread(() =>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(param =>
{
NetworkStream stream = tcpClient.GetStream();
string incomming;
byte[] bytes = new byte[1024];
int i = stream.Read(bytes, 0, bytes.Length);
incomming = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
form.console.Invoke(
(MethodInvoker)delegate
{
form.console.Text += String.Format(
"{0} Connection esatblished: {1}{2}",
DateTime.Now,
tcpClient.Client.RemoteEndPoint,
Environment.NewLine);
});
MessageBox.Show(String.Format("Received: {0}", incomming));
form.incommingMessages.Invoke((MethodInvoker)(() => form.incommingMessages.Items.Add(incomming)));
tcpClient.Close();
}, null);
}
});
listeningThread.IsBackground = true;
listeningThread.Start();
}
Client
private void button1_Click(object sender, EventArgs e)
{
Connect("localhost", "hello localhost " + Guid.NewGuid());
}
static void Connect(String server, String message)
{
try
{
Int32 port = 25565;
TcpClient client = new TcpClient(server, port);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
NetworkStream stream = client.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Length);
stream.Close();
client.Close();
}
catch (ArgumentNullException e)
{
Debug.WriteLine("ArgumentNullException: {0}", e);
}
catch (SocketException e)
{
Debug.WriteLine("SocketException: {0}", e);
}
}
Screenshot:
Create a thread, start to listen in it & don't stop the server
void CreateServer()
{
TcpListener tcp = new TcpListener(25565);
tcp.Start();
Thread t = new Thread(()=>
{
while (true)
{
var tcpClient = tcp.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((_) =>
{
//Your server codes handling client's request.
//Don't access UI control directly here
//Use "Invoke" instead.
tcpClient.Close();
},null);
}
});
t.IsBackground = true;
t.Start();
}
You could use the threads approach (as mentioned by other answers) or use asynchronous sockets, which in my opnion is way better. And even better, you can use the async model proposed by SocketAsyncEventArgs.
Async sockets will take benefits from using completion ports.
here is a good example on mdsn: Asynchronous server socket example