Teymur Hacizade
Teymur Hacizade

Reputation: 89

C# socket server with windows form application

I searched a lot but all examples in the internet are console application. I've tried use console application example for windows forms but when I call socket.start form freezes and status changes to (not response). Also I tried multiple threads but it's unsuccessful too. If it is possible please advice me something.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace mserver1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ServerClass sc = new ServerClass();
            sc.startServer(textBox1, richTextBox1);
        }
    }


    public class ServerClass
    {
        public void startServer(TextBox tb, RichTextBox rb)
        {

            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9939);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            socket.Bind(ip);
            socket.Listen(20);
            rb.Text = rb.Text + "Waiting for client...";
            Socket client = socket.Accept();
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

            rb.Text = rb.Text + "Connected with " + clientep.Address + " at port " + clientep.Port;

            string welcome = tb.Text;
            byte[] data = new byte[1024];
            data = Encoding.ASCII.GetBytes(welcome);
            client.Send(data, data.Length, SocketFlags.None);

            rb.Text = rb.Text + "Disconnected from" + clientep.Address;
            client.Close();
            socket.Close();
        }
    }
}

Thanks.

Upvotes: 6

Views: 38200

Answers (2)

Vanderley Maia
Vanderley Maia

Reputation: 485

I had the same problem, follow my solution for the SERVER

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;


using System.Threading;

namespace SERVER_WIN
{
    public partial class Form1 : Form
    {

        //Declare and Initialize the IP Adress
        static IPAddress ipAd = IPAddress.Parse("10.1.42.31");

        //Declare and Initilize the Port Number;
        static int PortNumber = 8888;

        /* Initializes the Listener */
        TcpListener ServerListener = new TcpListener(ipAd, PortNumber);
        TcpClient clientSocket = default(TcpClient);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Thread ThreadingServer = new Thread(StartServer);
            ThreadingServer.Start();
        }

        private void THREAD_MOD(string teste)
        {
            txtStatus.Text += Environment.NewLine + teste;
        }

        private void StartServer()
        {
            Action<string> DelegateTeste_ModifyText = THREAD_MOD;            
            ServerListener.Start();
            Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
            clientSocket = ServerListener.AcceptTcpClient();
            Invoke(DelegateTeste_ModifyText, "Server ready!");

            while (true)
            {
                try
                {

                    NetworkStream networkStream = clientSocket.GetStream();
                    byte[] bytesFrom = new byte[20];
                    networkStream.Read(bytesFrom, 0, 20);
                    string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
                    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                    string serverResponse = "Received!";
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                }
                catch
                {
                    ServerListener.Stop();
                    ServerListener.Start();
                    Invoke(DelegateTeste_ModifyText, "Server waiting connections!");
                    clientSocket = ServerListener.AcceptTcpClient();
                    Invoke(DelegateTeste_ModifyText, "Server ready!");
                }

            }
        }
    }
}

You will need to put in your windows forms just one control TextView, named txtStatus.

Client Program:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.IO;

namespace CLIENT_WIN
{
    public partial class Form1 : Form
    {
        TcpClient tcpclnt = new TcpClient();

        //Declare and Initialize the IP Adress
        IPAddress ipAd = IPAddress.Parse("10.1.42.31");

        //Declare and Initilize the Port Number;
        int PortNumber = 8888;

        public Form1()
        {
            InitializeComponent();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Console.WriteLine("Connecting.....");
            try
            {
                tcpclnt.Connect(ipAd, PortNumber);
                txtStatus.Text += Environment.NewLine + "Connected";
                txtStatus.Text += Environment.NewLine + "Enter the string to be transmitted";
            }
            catch { }
        }

        private void btnEnviar_Click(object sender, EventArgs e)
        {
            String str = txtEnviar.Text + "$";
            Stream stm = tcpclnt.GetStream();

            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] ba = asen.GetBytes(str);

            txtStatus.Text += Environment.NewLine + "Transmitting...";
            //Console.WriteLine("Transmitting.....");

            stm.Write(ba, 0, ba.Length);

            byte[] bb = new byte[100];
            int k = stm.Read(bb, 0, 100);

            string Response = Encoding.ASCII.GetString(bb);

            txtStatus.Text += Environment.NewLine + "Response from server: " + Response;

        }
    }
}

For the Client you will need put some controls; two TextViews (txtStatus and txtEnviar) and a button named btnEnviar, that is it!

You must run at first the Server, than you can run the client, if you need to stop the client, dont worry you can let the Server running.

Upvotes: 2

Sean H
Sean H

Reputation: 746

Your application will block until button1_Click returns.

You need to spawn a worker thread to do your listening. Additionally, you should not pass your controls directly into the worker thread. Rather, you should have a callback that will populate your controls with the data that comes from the socket communications.

Look up information on the BackgroundWorker. This will get you where you need to go.

Upvotes: 6

Related Questions