Once add user control into reference, visual studio turns to no responding? - c#

I test those code independently working fine. Once I write it into user control and add it into application reference, and use it in the WPF, Visual studio turns to "Not Responding". This drives me crazy.
below is the user control code:
namespace ServerUserContorl
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl
{
public Socket server;
public Socket Command_Listening_Socket; //used to listen for connections for exchanging commands between server and mobile
public Socket Interaction_Listening_Socket1;// designed for receiving information from mobile
public Socket Interaction_Listening_Socket2;// designed for sending information to mobile
public Socket Interaction_Receiving_Socket;// receiving
public Socket Interaction_Sending_Socket;// sending
public UserControl1()
{
IPAddress local = IPAddress.Parse("134.129.125.126");
IPEndPoint iepCommand = new IPEndPoint(local, 8080);// IP end point for command listening socket
IPEndPoint iepReceiving = new IPEndPoint(local, 8090);// IP end point for receiving socket
IPEndPoint iepSending = new IPEndPoint(local, 9090);// Ip end point for sending socket
//part for command listening socket connection
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(iepCommand);
server.Listen(20);
// part for receiving Socket
Interaction_Listening_Socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Interaction_Listening_Socket1.Bind(iepReceiving);
Interaction_Listening_Socket1.Listen(20);
// part for sending Socket
Interaction_Listening_Socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Interaction_Listening_Socket2.Bind(iepSending);
Interaction_Listening_Socket2.Listen(20);
while (true)
{
// Here is three blocks for accepting the new client,
// once client connect to the command listening socket,
// pass the command listening socket to the threadService class
// and start a thread for receiving the userID
Command_Listening_Socket = server.Accept();
Interaction_Receiving_Socket = Interaction_Listening_Socket1.Accept();
Interaction_Sending_Socket = Interaction_Listening_Socket2.Accept();
threadService service = new threadService(Command_Listening_Socket,Interaction_Receiving_Socket,Interaction_Sending_Socket);
Thread userCommand = new Thread(service.userCommand);
userCommand.Start();
Debug.WriteLine("thread starts");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Diagnostics;
using System.Threading;
namespace ServerUserContorl
{
class CommunicationThread
{
public Socket Interaction_Receiving_Socket, Interaction_Sending_Socket;
public CommunicationThread(Socket receiving, Socket sending)
{
Interaction_Receiving_Socket = receiving;
Interaction_Sending_Socket = sending;
}
// connect with iep2 9090, clientCom1,clientCommunication1
public void sendThread()
{
Debug.WriteLine("In the SendThread method");
byte[] bytes = new byte[1024];
string greeting = "hello, this is the message from the server.";
bytes = System.Text.Encoding.ASCII.GetBytes(greeting);
Debug.WriteLine("the byte is " + bytes);
int i = 0;
while (i < 10)
{
Interaction_Sending_Socket.Send(bytes);
Thread.Sleep(1000);
i++;
}
Debug.WriteLine("send is successful");
// clientCommunication1.Close();
}
//8080
public void receiveThread()
{
int i = 0;
string data = null;
Debug.WriteLine("In the receive method");
byte[] bytes = new byte[1024];
while ((i = Interaction_Receiving_Socket.Receive(bytes)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Debug.WriteLine("receive from the client " + data);
}
//clientCommunication.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using System.Threading;
namespace ServerUserContorl
{
class threadService
{
public Socket client;
//public Socket clientCommunication;
public string status;
public Socket Interaction_Receiving_Socket, Interaction_Sending_Socket;
public static int connections = 0;
int i = 0;
public threadService(Socket client,Socket receiving, Socket sending)
{
this.client = client;
Interaction_Receiving_Socket = receiving;
Interaction_Sending_Socket = sending;
}
public void userCommand()
{
string data = null;
byte[] bytes = new byte[1024];
if (client != null)
{
connections++;
}
Debug.WriteLine("new client connects, {0} connections", connections);
while ((i = client.Receive(bytes)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
status = data;
Debug.WriteLine("receive from client: " + status);
if (status == "1")
{
CommunicationThread communication = new CommunicationThread(Interaction_Receiving_Socket,Interaction_Sending_Socket);
Thread newSendThread = new Thread(communication.sendThread);
newSendThread.Start();
Debug.WriteLine("start the communication thread--status 1");
// CommunicationThread communication = new CommunicationThread();
Thread newReceiveThread = new Thread(communication.receiveThread);
newReceiveThread.Start();
Debug.WriteLine("start the communication thread--status 2");
}
}
}
}
}
In the WFP, I only add it:
xmlns:myControl="clr-namespace:ServerUserContorl;assembly=ServerUserContorl"
<myControl:UserControl1>

Visual Studio's Designer has to call the control's constructor when you add the control, which means the Designer is going into the while(true) loop in the constructor.
First: Do not put an infinite loop in your control's constructor. EVER. If you need something to poll endlessly, that should be handled in your program's main or, better yet, in a separate thread. Until the constructor finishes the control can't be referenced by other objects, so you need to let the constructor finish.
Second: If you have code in your constructor you want the Designer to skip, you can do this:
using System.ComponentModel;
public MyControl()
{
// code that Designer should run
if (LicenseManager.UsageMode == LicenseUsageMode.DesignTime)
return;
// code that Designer should not run
}

Related

C# UDP Packet Send & Receive

I'm trying to figure out how I can send & receive data via the UDP protocol using C# as a client, and having a JS server running that will transmit a "response" packet for testing purposes.
Below is the UDP class that I made for testing, it's simply just 2 threads:
One that read the received data from UDP and another thread for sending data.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace UDPTesting {
class UDPHandler {
private int receivePort, sendPort;
private string serverIP;
private IPEndPoint sendEndPoint, receiveEndPoint;
public UDPHandler(string serverIP, int receivePort, int sendPort) {
this.serverIP = serverIP;
this.receivePort = receivePort;
this.sendPort = sendPort;
this.sendEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.sendPort);
this.receiveEndPoint = new IPEndPoint(IPAddress.Parse(this.serverIP), this.receivePort);
this.readerUdpClient();
this.senderUdpClient();
}
void readerUdpClient() {
UdpClient readerClient = new UdpClient();
IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 3000);
readerClient.Client.Bind(localEndpoint); //Tried both Connect and Bind
//readerClient.Connect(this.receiveEndPoint);
Thread t = new Thread(() => {
Console.WriteLine("Awaiting data from server...");
var remoteEP = new IPEndPoint(IPAddress.Any, 3000);
byte[] bytesReceived = readerClient.Receive(ref remoteEP);
//The above throws: System.InvalidOperationException: 'You must call the Bind method before performing this operation'
Console.WriteLine("Received data from " + remoteEP.ToString());
});
t.Start();
}
void senderUdpClient() {
UdpClient senderClient = new UdpClient();
senderClient.Connect(this.sendEndPoint);
string sendString = "1;2;3";
byte[] bytes = toBytes(sendString);
Thread t = new Thread(() => {
while (true) {
senderClient.Send(bytes, bytes.Length);
Thread.Sleep(1000);
}
});
t.Start();
}
public byte[] toBytes(string text) {
return Encoding.UTF8.GetBytes(text);
}
public string fromBytes(byte[] bytes) {
return Encoding.UTF8.GetString(bytes);
}
}
}
Additionally my "main" for my program is this:
using System;
using System.Threading;
namespace UDPTesting {
class Program {
static void Main(string[] args) {
string serverIP = "46.101.102.243";
int sendPort = 41234;
int receivePort = 3000;
UDPHandler handler = new UDPHandler(serverIP, receivePort, sendPort);
}
}
}
How can I read the response that the server sends in the client, at the same time as I send data from the client to the server?
We tested it individually:
1) Sending a UDP packet from client -> server works, as I can see that the server receives the packet.
2) Sending a UDP packet from server -> client works, as I can see the client receives the packet.
3) When the client tries to send and read simultaneously, it will send data to the server, but will not read the response.
Any help would be greatly appreciated!
Your receiving function should work like this
void readerUdpClient()
{
new Thread(() => {
UdpClient readerClient = new UdpClient(receivePort);
Console.WriteLine("Awaiting data from server...");
var remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] bytesReceived = readerClient.Receive(ref remoteEP);
Console.WriteLine($"Received {bytesReceived.Length} bytes from {remoteEP}");
}).Start();
}
The UdpClient constructor that takes a port automatically binds the local end point for you.

Socket.Accept Throws Null Reference Exception

First of all, i'm new to all this Stack Overflow thingy.
I'm mostly a Unity programmer, but i need to run some code on my Pi and Unity can't build for it. Therefore, i'm using C# so i can later build with Mono.
I have a basic socket server code that runs off of unity, and it works fine.
I tried porting it over to VS but i always get a Null Ref Exception when calling Socket.Accept.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class RasPi
{
IPAddress ipAddress;
IPEndPoint localEndPoint;
Socket listener;
Socket handler;
int i = 0;
string data = string.Empty;
public string IP = "192.168.10.5";
public int Port = 5001;
static void Main(string[] args)
{
new RasPi().Initialize();
new RasPi().StartListening();
}
void Initialize()
{
i = 0;
ipAddress = IPAddress.Parse(IP);
localEndPoint = new IPEndPoint(ipAddress, Port);
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
}
public void StartListening()
{
try
{
while (true)
{
if (i == 0)
{
Console.WriteLine(listener.Accept());
handler = listener.Accept();
}
data = string.Empty;
while (true)
{
byte[] bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data = Encoding.ASCII.GetString(bytes, 0, bytesRec);
ProcessData(data);
handler.Send(bytes);
break;
}
//Restart();
Console.ReadKey();
break;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
/* void Restart()
{
i++;
StartListening();
}*/
public void ProcessData(string data)
{
switch (data)
{
}
}
}
Errors occur whenever i call listener.Accept();
In Unity, this worked fine. Anyone willing to help me here?
PS: I'm new to Networking, so i'm probably doing something stupid and i don't realise it.
You create 2 RasPi objects and call Initialize() and StartListening() on them individually. The second object won't have the same state as the first object that called Initialize() so StartListening() fails miserably. Instead, create one object and call both methods on it:
var rasPi = new RasPi();
rasPi.Initialize();
rasPi.StartListening();

Reset backlog after Socket server listen and response client

I am a newbie in C#, and I have developed a Socket program.
private static void SetupServer()
{
Console.WriteLine("Setting up server...");
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
serverSocket.Listen(1);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
But after server response a client, server is closed and not listen any time. How should I do to reset server after calling Listen(backlog) to maintain server for a long time?
This is my code in ClientSide:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PC_Client
{
public partial class Form1 : Form
{
private static Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public Form1()
{
InitializeComponent();
Console.ReadLine();
}
private void SendLoop()
{
string req = txtRequest.Text;
byte[] buffer = Encoding.ASCII.GetBytes(req);
clientSocket.Send(buffer);
byte[] receiveBuf = new byte[1024];
int rec = clientSocket.Receive(receiveBuf);
byte[] data = new byte[rec];
Array.Copy(receiveBuf, data, rec);
Console.WriteLine("Received: " + Encoding.ASCII.GetString(data));
}
private void LoopConnect()
{
int attempts = 0;
while(!clientSocket.Connected)
{
try
{
attempts++;
clientSocket.Connect(IPAddress.Loopback, 100);
}
catch (SocketException)
{
Console.WriteLine("Connection attempts: " + attempts.ToString());
}
}
//Console.Clear();
Console.WriteLine("Connected");
}
private void button1_Click(object sender, EventArgs e)
{
SendLoop();
}
}
}
I'm not sure about the particulars of C#, but in general, you want to wrap your accept call in a loop like so:
while(true) {
clientSocket = serverSocket.accept();
respond to socket in background thread
}
This way, your main thread will always be able to listen for sockets (because its wrapped in a while loop, and continues to accept new connections) while also not being blocked while handling a client request (because the client socket is handled in a background thread)

C# socket error, unable to send as socket is not connected?

I am trying to get to grips with sockets and it is proving a bit harder than I thought. I have googled this error and have tried to fix it myself by toying with my code but I do not understand what is not right here. The following code is giving me a socket exception with the error "A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied." As you can see I am trying this on my local machine, the client simply connects and sends a string. Any tips or pointers would be nice!
NOTE I have read other similar questions here on Stack Overflow but have not managed to fix my program with the solutions!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace Server
{
class Program
{
private static Socket socket = null;
private static Socket client = null;
private static IPAddress ipAddress = null;
private static int port = 1090;
private static IPEndPoint endPoint = null;
private static byte[] buffer;
private static int socketRecv = 0;
static void Main(string[] args)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ipAddress = IPAddress.Parse(GetLocalIPv4(NetworkInterfaceType.Ethernet));
endPoint = new IPEndPoint(ipAddress, port);
buffer = new byte[1024];
Console.WriteLine("\nVariables initialized...");
socket.Bind(endPoint);
socket.Listen(5);
Console.WriteLine("\nSocket bound and listening...");
client = socket.Accept();
Console.WriteLine("\nSocket accepted connection...");
//the program gets to here, then the exception is thrown
while (true)
{
if (socketRecv == 0)
{
socketRecv = socket.Receive(buffer);
continue;
}
Console.WriteLine("\nData wrote...\n");
break;
}
Console.WriteLine(System.Text.Encoding.Default.GetString(buffer));
Console.Read();
}
public static string GetLocalIPv4(NetworkInterfaceType _type)
{
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
}
}
return output;
}
}
}

How to make a Fully Async proxy (http 1.0 compiant not 1.1)

For a school project I am making a multi-client proxy that has to be compliant with http 1.0 and not 1.1(so that makes it easier). The teacher told me that it is better to make it fully async. So I made a fully async proxy, there is only one problem. It only works when I put a threadsleep in it, but this is not making it faster, but it's the only way to let it work. Please help me find a solution and maybe someone knows why it needs the threadsleep to let it work?
The teacher sees this problem every year and the only found solution is the threadsleep, so the teacher has not found a real solution.
First the simple code for the form. The form has a start button and a textbox to view the request and a textbox to view the responds. After the form follows the code for the proxy.
By the way, in internet explorer you can switch to a http 1.0 mode, so that's the best way to test, also you need to make the browser listen to a proxyserver(listed in de code).
using System;
using System.Windows.Forms;
using System.Threading;
namespace Proxy
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void startProxy_Click(object sender, EventArgs e)
{
var proxy = new Proxy(requestView, respondsView);
var thread = new Thread(new ThreadStart(proxy.StartProxy));
thread.IsBackground = true;
thread.Start();
startProxy.Enabled = false;
}
}
}
And now the proxy where the problem exists...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace Proxy
{
class Proxy
{
private TextBox requestView;
private TextBox respondsView;
private delegate void UpdateLogCallback(string strMessage, TextBox txtView);
public const int PROXY_PORT = 5008;
public const int WEB_PROXY_PORT = 80;
public const int BACKLOG = 20;
public const int TIMEOUT = 4000;
public Proxy(TextBox _requestView, TextBox _respondsView)
{
requestView = _requestView;
respondsView = _respondsView;
}
public void StartProxy()
{
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Unspecified);
clientSocket.Bind(new IPEndPoint(IPAddress.Any, PROXY_PORT));
clientSocket.Listen(BACKLOG);
clientSocket.BeginAccept(HandleConnection, clientSocket);
}
private void HandleConnection(IAsyncResult iar)
{
Socket clientSocket = iar.AsyncState as Socket;
Socket client = clientSocket.EndAccept(iar);
clientSocket.BeginAccept(HandleConnection, clientSocket);
SocketData data = new SocketData() { SocketToClient = client };
client.BeginReceive(data.buffer, 0, SocketData.BUFFER_SIZE, SocketFlags.None, OnDataArrived, data);
}
private void OnDataArrived(IAsyncResult iar)
{
SocketData socketdata = iar.AsyncState as SocketData;
int bytesreceived = 0;
UpdateLogCallback uLC = new UpdateLogCallback(ReceiveMessages);
socketdata.SocketToClient.ReceiveTimeout = TIMEOUT;
try
{
bytesreceived = socketdata.SocketToClient.EndReceive(iar);
if (bytesreceived == SocketData.BUFFER_SIZE)
{
socketdata.sb.Append(ASCIIEncoding.ASCII.GetString(socketdata.buffer, 0, bytesreceived));
socketdata.SocketToClient.BeginReceive(socketdata.buffer, 0, SocketData.BUFFER_SIZE, SocketFlags.None, OnDataArrived, socketdata);
}
else
{
socketdata.sb.Append(ASCIIEncoding.ASCII.GetString(socketdata.buffer, 0, bytesreceived));
string strContent = socketdata.sb.ToString();
string[] testing = strContent.Split(' ');
if (testing[0] == "CONNECT")
{
//this is to prevent weird request to microsoft servers(???) also prevents ssl request...
}
else
{
IPEndPoint ip = new IPEndPoint(Dns.GetHostEntry(GetHostnameFromRequest(strContent)).AddressList[0], WEB_PROXY_PORT);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Unspecified);
server.Connect(ip);
requestView.Invoke(new UpdateLogCallback(uLC), new object[] { strContent, requestView });
server.Send(System.Text.ASCIIEncoding.ASCII.GetBytes(strContent));
socketdata.SocketToServer = server;
server.BeginReceive(socketdata.buffer2, 0, SocketData.BUFFER_SIZE, SocketFlags.None, OnWebsiteDataArrived, socketdata);
}
}
}
catch
{
socketdata.SocketToClient.Close();
}
}
private void OnWebsiteDataArrived(IAsyncResult iar)
{
SocketData socketdata = iar.AsyncState as SocketData;
int bytesreceived = 0;
UpdateLogCallback uLC = new UpdateLogCallback(ReceiveMessages);
socketdata.SocketToServer.ReceiveTimeout = TIMEOUT;
try
{
bytesreceived = socketdata.SocketToServer.EndReceive(iar);
Thread.Sleep(10);
if (bytesreceived == SocketData.BUFFER_SIZE)
{
socketdata.sb2.Append(ASCIIEncoding.ASCII.GetString(socketdata.buffer2, 0, bytesreceived));
socketdata.SocketToClient.Send(socketdata.buffer2, 0, SocketData.BUFFER_SIZE, SocketFlags.None);
socketdata.SocketToServer.BeginReceive(socketdata.buffer2, 0, SocketData.BUFFER_SIZE, SocketFlags.None, OnWebsiteDataArrived, socketdata);
}
else
{
socketdata.sb2.Append(ASCIIEncoding.ASCII.GetString(socketdata.buffer2, 0, bytesreceived));
respondsView.Invoke(new UpdateLogCallback(uLC), new object[] { socketdata.sb2.ToString(), respondsView });
socketdata.SocketToClient.Send(socketdata.buffer2, 0, bytesreceived, SocketFlags.None);
socketdata.SocketToClient.Close();
socketdata.SocketToServer.Close();
}
}
catch
{
socketdata.SocketToClient.Close();
}
}
private static string GetHostnameFromRequest(string strContent)
{
string[] host = strContent.Split(new string[] { "\r\n", ": " }, StringSplitOptions.RemoveEmptyEntries);
int check = Array.IndexOf(host, "Host");
return host[check + 1];
}
public void ReceiveMessages(string receiveMessages, TextBox txtView)
{
if (txtView.InvokeRequired)
{
UpdateLogCallback uLC = new UpdateLogCallback(ReceiveMessages);
txtView.Invoke(new UpdateLogCallback(uLC), new object[] { receiveMessages, txtView });
}
else
{
txtView.AppendText(receiveMessages);
}
}
public class SocketData
{
public SocketData()
{
this.packetlenght = 0;
}
public Socket SocketToClient { get; set; }
public Socket SocketToServer { get; set; }
public StringBuilder sb = new StringBuilder();
public StringBuilder sb2 = new StringBuilder();
public const int BUFFER_SIZE = 128;
public byte[] buffer = new byte[BUFFER_SIZE];
public byte[] buffer2 = new byte[BUFFER_SIZE];
public int packetlenght { get; set; }
}
}
}
From Socket.EndReceive:
The EndReceive method will block until data is available. If you are using a connectionless protocol, EndReceive will read the first enqueued datagram available in the incoming network buffer. If you are using a connection-oriented protocol, the EndReceive method will read as much data as is available up to the number of bytes you specified in the size parameter of the BeginReceive method.
I read that to imply that (if you're on a slow network), it may return a size < SocketData.BUFFER_SIZE at any time, not just when you've received the end of the message. So the delay probably adds enough time that the only time it returns < SocketData.BUFFER_SIZE is once the message is complete.
You should go through your naming since it makes it hard to follow your code.
As an example: clientSocket is not a very good name for a listening socket.
Your exception handling is not good. At least log the exceptions.
And you need to check if the number of received bytes is zero. It indicates that the remote socket has closed the connection.
Your proxy thread will die directly since BeginAccept is not a blocking operation.
I do not understand your if in OnDataArrived. Why the check to see if the number of bytes is the same as the buffer size? TCP do not guarantee anything when it comes to received data. A partially filled buffer do not mean that the message is complete. Continue to build the buffer until the number of body bytes is the same as the specified Content-Length.
The same goes for OnWebsiteDataArrived. You are trying to use TCP in a way that it's not intended for. It's not message oriented. Keep building the buffer as suggested in #5.

Categories