my server / client project not working - c#

I have a server project with socket and a client project with socket in c#, that, when I start my server project, my form is not working, like is lock.
please help me...
What do I do for resolving that my form works and textbox shows messages?
private void button1_Click(object sender, EventArgs e)
{
try
{
port = 11000;
ip = IPAddress.Any;
IPEndPoint ipLocal = new IPEndPoint(ip, port);
socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketServer.Bind(ipLocal);
socketServer.Listen(10);
buffersize = 1024;//از این سایزه همه چی از گووره این در می آد
newClient = socketServer.Accept();
while (true)
{
buffer = new byte[buffersize];
recv = newClient.Receive(buffer, 0, buffer.Length, SocketFlags.None);
if (recv != 0)
{
message = Encoding.ASCII.GetString(buffer, 0, recv);
textBox1.Text += message;
//socketServer.Close();
//newClient.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
in client:
private void button1_Click(object sender, EventArgs e)
{
try
{
bufferSize = 1024;
ip = IPAddress.Parse("192.168.1.10");
port = 11000;
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEnd = new IPEndPoint(ip, port);
socketClient.Connect(ipEnd);
while (true)
{
buffer = new byte[bufferSize];
message = textBox1.Text;
buffer = Encoding.ASCII.GetBytes(message);
snd = socketClient.Send(buffer, 0, buffer.Length, SocketFlags.None);
//socketClient.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

In your Server :
You problem is due to blocking nature of Socket.Recieve() read .
It says :
If no data is available for reading, the Receive method will block until data is available
And you run this in same UI thread, so you feel your UI to be freeze.
Solution : Transfer your socket function to another thread. And to update text box, use Invokes.
Also in your implementation both Server and Client, you run a while loop infinitely. Since they are running in UI thread, you will feel the freeze.

Your applications locks up because you have an infinite loop in you click event handlers. You will have to start a Thread to do the read and write operations as not to block your main visualization thread.

Related

C# - Asynchronous server vs Synchronous server - sockets

I have some weird problem with two c# server sockets.
I have 2 servers. One is asynchronous and second is synchronous. I have also client in android which sends picture to this servers.
Synchronous Server:
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public void Start()
{
byte[] bytes = new Byte[1024000];
String content = String.Empty;
IPAddress ipAddress = IPAddress.Parse("192.168.1.2");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 53100);
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
//// Program is suspended while waiting for an incoming connection.
Socket handler = listener.Accept();
data = null;
// An incoming connection needs to be processed.
while (true)
{
bytes = new byte[1024000];
int bytesRec = handler.Receive(bytes);
strBuilder.Append(Encoding.ASCII.GetString(bytes, 0, bytesRec));
if (strBuilder.Length > 1)
{
content = strBuilder.ToString();
byte[] xdata = Convert.FromBase64String(content);
using (var mStream = new MemoryStream(xdata, 0, xdata.Length))
{
pictureBox1.Image = Image.FromStream(mStream, true);
}
}
}
byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void Form1_Load(object sender, EventArgs e)
{
thr = new Thread(new ThreadStart(Start));
thr.Start();
}
Asynchronous Server:
public void StartListening()
{
listener.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.2"), 53100));
listener.Listen(1);
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
public void AcceptCallback(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject stateObj = new StateObject();
stateObj.clientSocket = handler;
handler.BeginReceive(stateObj.buffer, 0, StateObject.buffSize, 0,
new AsyncCallback(ReadCallback), stateObj);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
public void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
StateObject stateObj = (StateObject)ar.AsyncState;
Socket handler = stateObj.clientSocket;
SocketError errorCode;
int bytesRead = handler.EndReceive(ar, out errorCode);
if (errorCode != SocketError.Success)
{
bytesRead = 0;
}
if (bytesRead > 0)
{
stateObj.strBuilder.Append(Encoding.ASCII.GetString(stateObj.buffer, 0, bytesRead));
handler.BeginReceive(stateObj.buffer, 0, stateObj.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), stateObj);
}
else
{
if (stateObj.strBuilder.Length > 1)
{
content = stateObj.strBuilder.ToString();
Debug.WriteLine(content);
byte[] data = Convert.FromBase64String(content);
using (var mStream = new MemoryStream(data, 0, data.Length))
{
pictureBox1.Image = Image.FromStream(mStream, true);
}
recImage = (Bitmap)pictureBox1.Image;
imgImage = new Image<Bgr, Byte>(recImage);
imageBox1.Image = imgImage;
while (imageBox1.Image != null)
{
SURFDetectionAndGUIUpdate(this, new EventArgs());
}
string xname = name.ToString();
Send(handler, xname);
}
}
}
private void Send(Socket handler, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
The problem is that when I send picture from client to synchronous server everything works and server receives it, but if I send picture from the same client to asynchronous server it doesn't receive it.
Currently your synchronous server attempts to create a bitmap from the data of the first Receive, and the asynchronous server waits until the client disconnects before trying to create a bitmap from the data.
TCP streams data, which means that you can read data as it arrives, in the order it was sent, but sending 1000 bytes doesn't mean you'll receive 1000 bytes at once. You could even receive data from two different message in a single Receive operation. The more data you send, and the more times you send data, the bigger the chance that this effect will occur.
In the comments you mention that the client is going to send multiple images, so before you continue you should decide how you want to determine when the first image is received and when data for the second image starts:
You could choose to let the client disconnect after sending each image, as the asynchronous server currently expects
You could choose to first send the number of bytes of an image, before sending the image data itself. Make sure the size itself is encoded at a fixed length. This prevents you from having to reconnect all the time, and also allows you to predetermine the size of the receive buffers
Or you could delimit the data using a byte outside the base64 range, but this requires scanning through the received data

How to listen socket in single ASP.NET page

I am developing client-server application using TCP Socekts and C#. I need to send message from console application to ASP page. I can connect from ASP page using OnLoad event and sometimes on PageLoad event I can receive several messages only. I have 2 questions:
1. How to listen continuously the server socket and receive messages?
2. How to know when the ASP.NET page closed (by user) to disconnect from server?
Server Console App:
static void StartServer()
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(4);
ConsoleKeyInfo cki;
XmlDocument doc = new XmlDocument();
doc.Load("test.xml");
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
Console.WriteLine("Server started " + DateTime.Now + Environment.NewLine);
Console.WriteLine("Press S to start Data Sharing or ESC key to quit" + Environment.NewLine);
do
{
cki = Console.ReadKey();
if (cki.Key == ConsoleKey.S)
{
foreach (XmlNode node in doc.DocumentElement.ChildNodes)
{
try
{
_client = (ClientInfo)clientList[0];
if (((ClientInfo)clientList[0]).strName == node.Attributes["type"].InnerText)
{
SendRecord(node.Attributes["type"].InnerText + node.Attributes["value"].InnerText, (ClientInfo)clientList[0]);
clientList.Insert(clientList.Count, (ClientInfo)clientList[0]);
clientList.RemoveAt(0);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.message);
}
}
Console.WriteLine("Data sharing finished " + DateTime.Now);
}
} while (cki.Key != ConsoleKey.Escape);
}
static void SendRecord(string _msg, ClientInfo client)
{
Data msgToSend = new Data();
msgToSend.cmdCommand = Command.Message;
msgToSend.strMessage = _msg;
byte[] byteData = msgToSend.ToByte();
try
{
client.socket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnSend), _client);
Thread.Sleep(3);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
ASP.NET client side:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
Connect();
}
protected void Page_OnClose(object sender, EventArgs e)
{
Disconnect();
}
protected void updateEvent(object sender, EventArgs e)
{
if (msglist.Count > 0) lstRecords.Items.Add(msg);
lstRecords.Height = Unit.Percentage(100);
}
private void Connect()
{
Data msgToSend = new Data();
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 1000);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
msgToSend.strType = strType;
msgToSend.strMessage = null;
msgToSend.cmdCommand = Command.List;
byteData = msgToSend.ToByte();
try
{
clientSocket.BeginConnect(ipEndPoint, new AsyncCallback(OnConnect), null);
clientSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
byteData = new byte[1024];
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
}
catch (Exception ex)
{
lstRecords.Items.Add(ex.Message);
}
}
Server App is sending to WinApp and ConsoleApp without any problem. But with ASP page, I can correctly receive only Connect message and sometimes i can receive 1-2-3 msg only. I am using javascript setInterval("__doPostBack('upDynamicClock', '');", 1000); to refresh page
HTTP is stateless, ASP.NET WebForms only tries to hide this with viewstate and such. As soon as you see the page in your browser, the page isn't alive anymore and your OnSend callback won't be called anymore. This is also explained in Create web page with live socket based data.
If your goal is to update an HTML element with server-fed data, take a look at SignalR.

C# TCP Client having trouble listening to Server and updating GUI

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.

Socket connection in CF 3.5 C#

I am trying to establish a communication between a handheld and a PC.
I have the following code, for the client:
public void connect(string IPAddress, int port)
{
// Connect to a remote device.
try
{
IPAddress ipAddress = new IPAddress(new byte[] { 192, 168, 1, 10 });
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
if (connectDone.WaitOne()){
//do something..
}
else{
MessageBox.Show("TIMEOUT on WaitOne");
}
}
catch(Exception e){
MessageBox.Show(e.Message);
}
}
My problem is that when I run both of them in a pc they communicate fine, but the same code in a SmartDevice Project doesn't connect with the Server which is running on the PC and it give me this error:
System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or stablished connection failed
because connected host has failed to respond
What am I missing?
NOTE: The IPAddress is hard coded inside the code
EDIT: here is another code which I take from a MSDN example. This don't work either, it says that it not possible to read. The server code in this case is the same as the example, the client code have a modification:
private void button1_Click(object sender, EventArgs e)
{
// In this code example, use a hard-coded
// IP address and message.
string serverIP = "192.168.1.10";//HERE IS THE DIFERENCE
string message = "Hello";
Connect(serverIP, message);
}
Thanks in advance for any help!
For my "mobile device" client, I send data to the "PC" host using this:
private void Send(string value) {
byte[] data = Encoding.ASCII.GetBytes(value);
try {
using (TcpClient client = new TcpClient(txtIPAddress.Text, 8000)) {
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
}
} catch (Exception err) {
// Log the error
}
}
For the host, you're best to use a thread or BackgroundWorker where you can let a TcpListener object sit and wait:
private void Worker_TcpListener(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = (BackgroundWorker)sender;
do {
string eMsg = null;
int port = 8000;
try {
_listener = new TcpListener(IPAddress.Any, port);
_listener.Start();
TcpClient client = _listener.AcceptTcpClient(); // waits until data is avaiable
int MAX = client.ReceiveBufferSize;
NetworkStream stream = client.GetStream();
Byte[] buffer = new Byte[MAX];
int len = stream.Read(buffer, 0, MAX);
if (0 < len) {
string data = Encoding.UTF8.GetString(buffer);
worker.ReportProgress(len, data.Substring(0, len));
}
stream.Close();
client.Close();
} catch (Exception err) {
// Log your error
}
if (!String.IsNullOrEmpty(eMsg)) {
worker.ReportProgress(0, eMsg);
}
} while (!worker.CancellationPending);
}

building a C# asynchronous TCP proxy server

I am attempting to build a simple C# TCP proxy for my business so I can block certain websites from my employees. All is well except I am having trouble seeing what website the user is trying to visit... I can see that the user has connected to my proxy server so I know I am getting connections but the OnRecieve callback isn't even firing. Am I reading from the socket wrong?
Here is my code:
internal class AsyncState
{
public const int BufferSize = 4096;
public byte[] Buffer = new byte[AsyncState.BufferSize];
public Socket Socket;
public StringBuilder Content = new StringBuilder();
}
private void OnLoad(object sender, EventArgs e)
{
IPAddress[] addressCollection = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress ipAddress in addressCollection)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
localEndPoint = new IPEndPoint(ipAddress, 8080);
Console.WriteLine("Local IP address found... " + localEndPoint.ToString());
break;
}
}
isListening = true;
thread = new Thread(new ThreadStart(
delegate()
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(localEndPoint);
serverSocket.Listen(10);
while (isListening)
{
resetEvent.Reset();
Console.WriteLine("Waiting for clients...");
serverSocket.BeginAccept(new AsyncCallback(OnAccept), serverSocket);
resetEvent.WaitOne();
}
}));
thread.Start();
}
}
private void OnAccept(IAsyncResult result)
{
resetEvent.Set();
Socket clientSocket = (result.AsyncState as Socket).EndAccept(result);
Console.WriteLine("Client has connected... " + clientSocket.RemoteEndPoint.ToString());
AsyncState state = new AsyncState();
state.Socket = clientSocket;
state.Socket.BeginReceive(state.Buffer, 0, AsyncState.BufferSize, SocketFlags.None, new AsyncCallback(OnRecieve), state);
}
private void OnRecieve(IAsyncResult result)
{
AsyncState state = result.AsyncState as AsyncState;
int totalRead = state.Socket.EndReceive(result);
if (totalRead > 0)
{
state.Content.Append(Encoding.ASCII.GetString(state.Buffer, 0, totalRead));
state.Socket.BeginReceive(state.Buffer, 0, AsyncState.BufferSize, SocketFlags.None, new AsyncCallback(OnRecieve), state);
}
else
{
if (state.Content.Length > 1)
Console.WriteLine("Message recieved from client... " + state.Content.ToString());
state.Socket.Close();
}
}
Building a well working proxy is no simple task as you will have to understand and handle HTTP etc. in both directions...
I would recommend to either use an existing library for that OR some configurable proxy...
http://www.mentalis.org/soft/projects/proxy/ (with source)
http://sourceforge.net/p/portfusion/home/PortFusion/ (with source)
http://www.wingate.com/
http://www.squid-cache.org/
REMARK:
I don't know in which jurisdiction you are but using such technology without knowledge/consent of employees can in some places be a problem...
Another point: Instead of using such methods I would tell the employee to stop abusing the internet connection of the company 1-3 times and if that doesn't work I would rather fire that person... such employees is not only abusing the internet connection of the company but in worstcase is putting the company at risk (virus/trojan etc.) and also defrauding the company (if he does this in work hours)...

Categories