1

I created an server-client app in c#. I manage to send messages from client to server and read them, but i don't know how to send message back from server to client.

Here is my server: enter image description here

namespace TCPSockets {
    public partial class Form1 : Form {

        TcpClient client = null;
        TcpListener listener = null;
        IPAddress ip = null;
        int port = 1337;

        Thread thClient = null;
        Thread thListener = null;


        NetworkStream dataStream = null;


        public Form1() {
            InitializeComponent();
            txt_ip.Text = "127.0.0.1";
            txt_port.Text = "1234";
        }

        private void ListenForConnections() {
            listener = new TcpListener(ip, port);
            listener.Start();

            while (true) {
                try {
                    client = listener.AcceptTcpClient(); 


                    dataStream = client.GetStream();

                    byte[] message = new byte[1024];
                    dataStream.Read(message, 0, message.Length);
                    dataStream.Close();

                    string strMessage = Encoding.UTF8.GetString(message);
                    MessageBox.Show("Server: I got message: " + strMessage);
                }

                catch (Exception ex) {
                    thListener.Join();  
                }
            }
        }




        private void start_server_Click(object sender, EventArgs e)
        {
            ip = IPAddress.Parse(txt_ip.Text);
            port = Convert.ToInt32(txt_port.Text);

            // nit => sicer vmesnik blokira, ko kličemo AcceptTcpClient()
            thListener = new Thread(new ThreadStart(ListenForConnections));
            thListener.IsBackground = true;
            thListener.Start();
        }
    }
}

And here is my client: enter image description here

namespace TCPSockets {
    public partial class Form1 : Form {

        TcpClient client = null;
        TcpListener listener = null;
        IPAddress ip = null;
        int port = 1337;


        Thread thClient = null;
        Thread thListener = null;


        NetworkStream dataStream = null;


        public Form1() {
            InitializeComponent();
            txt_ip.Text = "127.0.0.1";
            txt_port.Text = "1234";
        }


        private void SendPacket(object pClient) {
            string message = txt_message.Text;

            try {
                client = (TcpClient)pClient; 
                client.Connect(ip, port);   

                dataStream = client.GetStream();
                byte[] strMessage = Encoding.UTF8.GetBytes(message);
                dataStream.Write(strMessage, 0, strMessage.Length);
                dataStream.Close(); 
                client.Close();  
            }
            catch (Exception ex) {
                MessageBox.Show("Odjemalec: Pošiljanje ni bilo uspešno!");
            }
        }


        private void send_to_server_Click(object sender, EventArgs e)
        {
            ip = IPAddress.Parse(txt_ip.Text);
            port = Convert.ToInt32(txt_port.Text);

            client = new TcpClient();
            thClient = new Thread(new ParameterizedThreadStart(SendPacket));
            thClient.IsBackground = true;
            thClient.Start(client);

        }
    }
}

Does anyone know how to properly send message to client from server and read it in client?

kac26
  • 381
  • 1
  • 7
  • 25
  • First the client has to connect to the server. Then have the server write to the stream and the client read from the stream. It's not much different from what you already have. – AlexDev Apr 13 '17 at 17:05
  • Try following : listener.Server.Send – jdweng Apr 13 '17 at 17:06
  • You can send messages from server to client in exactly the same way you send from client to server. Just don't close the socket. Make sure you read available references, including the MSDN samples and the very useful [Winsock Programmer's FAQ](http://tangentsoft.net/wskfaq/). It was written pre-.NET for Winsock programmers, but the .NET API is only a thin layer over Winsock, and most of the advice there still applies exactly. – Peter Duniho Apr 13 '17 at 17:28

2 Answers2

0

If you want to use the same code that you are currently using, you would just need to implement both Server and Client roles on both your "Server" and your "Client" computers. Then when you want the "Server" computer to send, it will be acting as a Client role and sending to your "Client" computer acting as a Server role. You will need both computers listening for messages from the other. I would recommend they also listen on different ports so you don't have to modify your code more than needed. Based on Tobias's comment, could cause more complexity and that is why I recommend using SignalR but that is not an answer for this question, it is an alternative.

If you don't mind using a new codebase, one solution I would highly recommend exploring is SignalR. SignalR is a technology that allows for the "Pushing" of notifications and would allow you to accomplish what you are aiming to do very easily. Here is a great simple example:

https://github.com/SignalR/Samples/tree/master/Samples_2.1.0/ConsoleClient

This would allow you to invoke messages as easy as:

await _connection.Send(new { Type = "sendToMe", Content = "Hello World!" });

It is supported on many platforms and has a lot of tutorials!

Here is a link to the samples repository on GitHub. Another method of performing this using SignalR is outlined here along with an OWIN Self Hosting method: SignalR Console app example

Community
  • 1
  • 1
  • Not a good idea to have Server AND Client on both, except both sides need to be able to start the communication. One Server can easily talk to one client and vice versa. Better do it right than to double the problems. – Tobias Knauss Apr 13 '17 at 18:53
0

When the Server (TcpListener) accepts an incoming connection from a Client (TcpClient), it will create the server-side TcpClient. See MSDN TcpListener.AcceptTcpClient

So you will have 2 of them: one that you created in the client program, and one that was created automatically by the TcpListener.

Just use TcpClient.GetStream() to get the underlying network stream on both and you'll be able to communicate by using NetworkStream.Read() and .Write(). That's it.

For testing and debugging network connections I recommend the use of HWGroup Hercules and SysInternals TcpView.

Tobias Knauss
  • 3,361
  • 1
  • 21
  • 45