C# socket server with windows form application - c#

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.

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.

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.

Related

TCP/IP Using BeginReceive in a Loop

I am currently trying to make a chess application with two clients and one server, lets say client1 and client2 are trying to speak to each other. the server side is ok but the client side is a little corrupted. The application has a chat part and when client1 wants to speak client2, client2 should receive the message immediately. When i put the BeginReceive line in a loop, client2 receives at the moment the message is sent but then connection problem occurs. If i dont make a loop with BeginReceive, then application has no errors but when client1 sends the message, client2 doesnt see the message immediately. Only when, client2 sends a message to client1, client1's first message is seen in the chat. can you help me about it?
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;
namespace ChessClient
{
public partial class Form1 : Form
{
private Socket client;
private byte[] data = new byte[1024];
private int size = 1024;
public Form1()
{
InitializeComponent();
sendbtn.Click += new EventHandler(ButtonSendOnClick);
connectbtn.Click += new EventHandler(ButtonConnectOnClick);
disconnectbtn.Click += new EventHandler(ButtonDisconOnClick);
}
void ButtonConnectOnClick(object obj, EventArgs ea)
{
conStatus.Text = "Connecting...";
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9060);
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
}
void ButtonSendOnClick(object obj, EventArgs ea)
{
byte[] message = Encoding.ASCII.GetBytes(chat.Text);
chat.Clear();
client.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(SendData), client);
}
void ButtonDisconOnClick(object obj, EventArgs ea)
{
client.Close();
conStatus.Text = "Disconnected";
}
void Connected(IAsyncResult iar)
{
client = (Socket)iar.AsyncState;
try
{
client.EndConnect(iar);
conStatus.Text = "Connected to: " + client.RemoteEndPoint.ToString();
This is where i put inside the loop, beginreceive was in an infinite loop
client.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), client);
}
catch (SocketException)
{
conStatus.Text = "Error connecting";
}
}
void ReceiveData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceive(iar);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
chatBox.Items.Add(stringData);
}
void SendData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
remote.EndSend(iar);
remote.BeginReceive(data, 0, size, SocketFlags.None,
new AsyncCallback(ReceiveData), remote);
}
}
}

Permanent receiving of sent XML over TCP

C# Form .Net 4.7
A client app should receive XML data from an external payment machine. The XML is automatically sent after each deposit. It's about receiving it at any time and displaying it in a TextBox.
Sending takes place via TCP
The machine opens the connection to the external system at the specified port
Sends the data
Waits for confirmation on the same connection if necessary
Closes the connection
Since the client has to be able to receive the data at any time, I thought about a listener. But I'm not sure if this approach is the right one. What I did here doesn't work. I wanted to test that with a localhost. There is sure to be a simple solution. But since I'm not a network specialist, I can't find it. Does anyone know how to do it best?
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.Xml;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace TCPListener
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpListener Listener = null;
Int32 port = 8080;
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
private void button1_Click(object sender, EventArgs e)
{
Listener = new TcpListener(localAddr, port);
byte[] receiveBuffer = new byte[10025];
while (true)
{
int requestCount = 0;
Listener.Start();
MessageBox.Show(" >> Listener Started");
using (var tcpClient = Listener.AcceptTcpClient())
{
MessageBox.Show(" >> Accepted connection from client");
using (var networkStream = tcpClient.GetStream())
{
while (true)
{
try
{
requestCount = requestCount++;
var bytesRead = networkStream.Read(receiveBuffer, 0, (int)tcpClient.ReceiveBufferSize);
if (bytesRead == 0)
{
// Read returns 0 if the client closes the connection
break;
}
string dataFromClient = System.Text.Encoding.ASCII.GetString(receiveBuffer, 0, bytesRead);
XmlDocument xm = new XmlDocument();
xm.LoadXml(string.Format("<root>{0}</root>", dataFromClient));
XmlElement root = xm.DocumentElement;
string rootName = root.FirstChild.Name;
textBox1.Text = (rootName, dataFromClient);
}
catch (Exception ex)
{
MessageBox.Show("ReceivePortMessages: " + ex.ToString());
break;
}
}
}
MessageBox.Show(" >> stopped read loop");
}
Listener.Stop();
}
}
}
}

How to get TCP connection ids of all connected clients in c# console application

How can i get TCP Connection ID of all the connected clients.Actually i am making a program in c# (console application) that will return array with Connection Ids and IMEIs of connected clients. below code is simple client and server program so how can i get Connection id ?
Client Program :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net.Sockets;
namespace TcpEchoClient
{
class TcpEchoClient
{
static void Main(string[] args)
{
Console.Title = "TCP Client";
String server = "xxx.xxx.x.xx"; // IP address
byte[] byteBuffer = Encoding.ASCII.GetBytes("Test Message");
int servPort = 1;
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = new TcpClient(server, servPort);
Console.WriteLine("Connected to server... sending echo string");
netStream = client.GetStream();
netStream.Write(byteBuffer, 0, byteBuffer.Length);
Console.WriteLine("Sent {0} bytes to server...", byteBuffer.Length);
int totalBytesRcvd = 0;
int bytesRcvd = 0;
while (totalBytesRcvd < byteBuffer.Length)
{
if ((bytesRcvd = netStream.Read(byteBuffer, totalBytesRcvd, byteBuffer.Length - totalBytesRcvd)) == 0)
{
Console.WriteLine("Connection closed prematurely.");
break;
}
totalBytesRcvd += bytesRcvd;
}
Console.WriteLine("Received {0} bytes from server: {1}", totalBytesRcvd, Encoding.ASCII.GetString(byteBuffer, 0, totalBytesRcvd));
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
netStream.Close();
client.Close();
}
}
}
}
Server Program :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
sing System.Net;
using System.Net.Sockets;
namespace TcpEchoServer
{
class TcpEchoServer
{
private const int BUFSIZE = 32;
static void Main(string[] args)
{
Console.Title = "TCP Server";
int servPort = 1;
TcpListener listener = null;
try
{
listener = new TcpListener(IPAddress.Any,servPort);
listener.Start();
}
catch(SocketException se)
{
Console.WriteLine(se.ErrorCode + ": " + se.Message);
Environment.Exit(se.ErrorCode);
}
byte[] rcvBuffer = new byte[BUFSIZE];
int bytesRcvd;
for (; ; )
{
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = listener.AcceptTcpClient();
netStream = client.GetStream();
Console.Write("Handling client - ");
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer,0,rcvBuffer.Length)) >0)
{
netStream.Write(rcvBuffer,0,bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
netStream.Close();
client.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
netStream.Close();
}
}
}
}
}
Can anyone point me in the right direction?
Thanks in advance.

How to enable a custom IP-address for a UDP packet sender?

So i'm making a little UDP packet sender, but I have a problem. I have it set so that when the user clicks "button 2" they will automatically send a packet to the IP which I have specified. How can I make it so that the user can put there own IP address in and that becomes the IP which a packet is sent to? Here is the code I have so far:
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.Threading;
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace ProjectTakedown
{
public partial class Form1 : Form
{
public Form1() //where the IP should be entered
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e) //button to start takedown
{
byte[] packetData = System.Text.ASCIIEncoding.ASCII.GetBytes("<Packet OF Data Here>");
string IP = "127.0.0.1";
int port = 80;
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IP), port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.SendTo(packetData, ep);
}
private void Stop_Click(object sender, EventArgs e)
{
}
}
}
Also how do I get the stop button to stop the process?
You could have a TextBox on the GUI that allows the user to input a string representing the IP address and when the button is clicked you take the contents and use them to send the packet:
private void button2_Click(object sender, EventArgs e) //button to start takedown
{
byte[] packetData = System.Text.ASCIIEncoding.ASCII.GetBytes("<Packet OF Data Here>");
string IP = textBox1.Text; // take input by user
int port = 80;
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(IP), port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.SendTo(packetData, ep);
}

manually input in textbox and connected to the server

Right now, when i press the connect button i will be connected to the server by the default ip address and port number. clientSocket.Connect("127.0.0.1", 8888);
I would like to create 2 textbox in the GUI , 1 for the IP address and 1 for port.
So that user can manually key in the IP add and port.
May i know how to do this. thanks.
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.Sockets;
using System.Threading;
namespace SocketClient
{
public partial class SocketClient : Form
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream = default(NetworkStream);
string readData = null;
public SocketClient()
{
InitializeComponent();
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textDisplay.Text = textDisplay.Text + Environment.NewLine + " >> " + readData;
}
private void buttonConnect_Click(object sender, EventArgs e)
{
readData = "Conected to NYP Chat Server ...";
msg();
//
clientSocket.Connect("127.0.0.1", 8888);
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textName.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
private void buttonSend_Click(object sender, EventArgs e)
{
}
private void textDisplay_TextChanged(object sender, EventArgs e)
{
}
}
}
In the designer view, add two TextBoxes in the desired positions and name the texbboxes as tbIp and tbPort.
update the line following line
clientSocket.Connect("127.0.0.1", 8888);
to
clientSocket.Connect(tbIp.Text, Convert.Int32(tbPort.Text));
Regards
ArunDhaJ

Categories

Resources