Detecting client disconnection by server c# - c#

I have written code for server and multiple client using threads and sockets. Normally the clients exits by sending the 'exit' keyword to server but I want the server to also detect situation when the clients exits forcefully without sending 'exit' keyword to server, for example when user in middle of sending message to server presses cross button of client window. What I want is that server should detect this situation and displays some error code and continue receiving message from other clients connected to it.
Second problem I am facing how can I disconnect server even if multiple clients are connected to it. In my code I am using tcpListener.Stop() but when i use this method error message "server failed to start at ipaddress" is displayed and number of such windows opens is equivalent to number of clients server is listening. For example if server is listening to 1000 clients then 1000 such windows will open showing the earlier mentioned error message which doesn't look good from the point of person using this software. So How can I handle this situation? Also in this situation if clients again starts sending message to the server then is also starts receiving messages even though I have disconnected the server. The server should remain disconnected until the user restarts server.
Following is my code for server.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// Constants IP address of server and maximum number of clients server can connect.
static class Constants
{
public const string IP = "127.0.0.1";
public const int No_Of_Clients = 2;
}
// server port number
int port_number;
static IPAddress ipAddress = IPAddress.Parse(Constants.IP);
TcpListener tcpListener;
public Form1()
{
InitializeComponent();
button1.Click += button1_Click;
button2.Click += button2_Click;
//this.FormClosing += Form1_FormClosing;
}
//Socket socketForClient;
private void button1_Click(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(textBox1.Text.Trim()))
{
System.Windows.Forms.MessageBox.Show("Port Number Empty", "Error");
}
else
{
port_number = int.Parse(textBox1.Text);
createserver(Constants.No_Of_Clients);
serveripaddress();
infoBox1.Text = string.Format("The server is now listening at port {0} at ip address {1}", port_number, Constants.IP);
infoBox1.Text = infoBox1.Text + "\r\n" + string.Format("The server can listen to maximum {0} number of clients", Constants.No_Of_Clients);
}
}
// this code disconnects the server
private void button2_Click(object sender, EventArgs e)
{
try
{
tcpListener.Stop();
}
catch (Exception f)
{
MessageBox.Show(f.Message);
}
}
public void serveripaddress()
{
serverip.Text = "Server IP : " + Constants.IP;
//serverport.Text = "Port Number : " + port.ToString();
}
// Starts server
private void createserver(int no_of_clients)
{
tcpListener = new TcpListener(ipAddress, port_number);
tcpListener.Start();
for (int i = 0; i < no_of_clients; i++)
{
Thread newThread = new Thread(new ThreadStart(Listeners));
newThread.Start();
}
} // end of createserver();
//listen to client receiving messages
public void Listeners()
{
Socket socketForClient;
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch
{
System.Windows.Forms.MessageBox.Show(string.Format("Server failed to start at {0}:{1}", Constants.IP, port_number), "Error");
return;
}
if (socketForClient.Connected)
{
//System.Windows.Forms.MessageBox.Show("hello");
string string1 = string.Format("Client : " + socketForClient.RemoteEndPoint + " is now connected to server.");
infoBox1.Text = infoBox1.Text + "\r\n" + string1;
NetworkStream networkStream = new NetworkStream(socketForClient);
System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);
string theString = "";
while (true)
{
try
{
theString = streamReader.ReadLine();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
// if (streamReader.ReadLine() == null )
//{
// System.Windows.Forms.MessageBox.Show(string.Format("Server failed to start at {0}:{1}", Constants.IP, port_number), "Error");
// }
if (theString != "exit")
{
textBox2.Text = textBox2.Text + "\r\n" + "-----------------------------------------------------------------------------------";
string string2 = string.Format("Message recieved from client(" + socketForClient.RemoteEndPoint + ") : " + theString);
textBox2.Text = textBox2.Text + "\r\n" + string2;
// ASCII code for the message from client
string string3 = string.Format("ASCII Code for message is : ");
textBox2.Text = textBox2.Text + "\r\n" + string3;
string string4 = "";
foreach (char c in theString)
{
string4 += string.Format(System.Convert.ToInt32(c) + " ");
}
textBox2.Text = textBox2.Text + string4;
// Hex value of message from client
string hex = "";
foreach (char c in theString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
string string5 = string.Format("Hex Code for the message from client : " + hex);
textBox2.Text = textBox2.Text + "\r\n" + string5;
//sending acknowledgement to client
try
{
socketForClient.Send(new ASCIIEncoding().GetBytes("The string was recieved from Client(" + socketForClient.RemoteEndPoint + ") : " + theString));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
} // end of if loop
// if exit from client
else
{
string string7 = string.Format("Client " + socketForClient.RemoteEndPoint + " has exited");
infoBox1.Text = infoBox1.Text + "\r\n" + string7;
break;
}
} // end of while loop
streamReader.Close();
networkStream.Close();
streamWriter.Close();
} // end of if loop
socketForClient.Close();
}
}
}

To be informed about closed client connections you have to send periodically a 'heartbeat' message to the client. If the client connection died the tcp/ip mechanism will inform you after the timeout that the connection died (can't remember the name of the exception).
If the client wants to know if the connection died he has also to send a heartbeat message.
This is needed as the tcp connection recognizes lost connections only if data is sent over this connection.
For the second problem you should keep a list of all the active clients (your variable socketForClient). When you want to end your server you close all the client connections (the clients in the list).

Related

TcpClient hangs

I am working on a simple Client to send data to a server at my office. I tested the code locally on my computer using a server called TCPServer, I connect, send data, receive reply, disconnect, send again, rinse and repeat, it all works perfectly, but when I connect to office and do the same thing it connects fine, I can connect/disconnect forever, but when I send data it just hangs. Nothing is received in the log at the office. I can't send a single byte there.
Seems like a firewall issue doesn't it.
But I can run an older program I wrote years ago in Delphi (pascal), and it connects and sends the same data over without issue, same port, everything, so the problem is not a firewall issue. Thoughts on this? Here is the basic code layout.
Connect Button
Disconnect Button
Send Button
At the top of the class I declare the TcpClient Variable
public TcpClient m_client = new TcpClient();
In the _Click for Connect Button and Disconnect Button I have code to connect to server and set some indicators etc
private void ConnectButton_Click(object sender, EventArgs e)
{
string address = FixIP(IPAddressMaskedTextBox.Text);
int Port = Convert.ToInt32(PortNumberMaskedTextBox.Text);
Control control = (Control)sender;
String name = control.Name;
try
{
switch (name)
{
case ("ConnectButton"):
//Connect to server
connect(address, Port);
if (m_client.Connected)
{
SingleConnectionRichTextBox.Clear();
ConnectedLightButton.BackColor = Color.Lime;
SingleConnectionRichTextBox.Text += "Connected at IP " + address + " and Port " + Port.ToString() + "\r\n";
}
break;
case ("DisconnectButton"):
if (m_client.Connected)
{
SingleConnectionRichTextBox.Text += "Connection Terminated\r\n";
ConnectedLightButton.BackColor = Color.Red;
m_client.Client.Disconnect(false);
m_client = new TcpClient();
}
break;
}
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
public void connect(string address, int port)
{
try
{
if (!m_client.Connected)
{
ConnectedLightButton.BackColor = Color.Yellow;
SingleConnectionRichTextBox.Text += "Attempting to Connect...\r\n";
m_client.Connect(address, port);
}
else
{
SingleConnectionRichTextBox.Text += "Connection Failed...\r\n";
ConnectedLightButton.BackColor = Color.Red;
throw new Exception("Connect: Already connected\r\n");
}
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
The Send button has it's own event, mostly because when connecting to office it can take a minute for sockets to be created etc.
private void SendButton_Click(object sender, EventArgs e)
{
try
{
if (m_client.Connected)
{
string completeString = "";
for (int cnt = 0; cnt < SingleSendRichTextBox.Lines.Count() - 1; cnt++)
{
string aLine = Regex.Replace(SingleSendRichTextBox.Lines[cnt], #"\e\[(\d+;)*(\d+)?[ABCDHJKfmsu]", "");
if (cnt == 0)
{
//First line gets Start Block, plus a CR on end
aLine = (char)0x0B + aLine + (char)0x0D;
}
else if (cnt == (SingleSendRichTextBox.Lines.Count() -1))
{
//Last line gets CR + End Block + CR on end
aLine += (char)0x0D + (char)0x1C + (char)0x0D;
}
else
{
//All middle lines get CR on end
aLine += (char)0x0D;
}
//MessageBox.Show("Sending line# " + cnt.ToString() + " = " + aLine);
completeString += aLine;
}
Byte[] data = Encoding.ASCII.GetBytes(completeString);
WriteBytes(data);
ReadAllBytes();
}
else
{
MessageBox.Show("Nothing is connected currently...");
}
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
public void WriteBytes(Byte[] data)
{
try
{
if ((m_client.Connected)&&(data.Count() > 0))
{
// Get access to network stream
NetworkStream stm = m_client.GetStream();
stm.Write(data, 0, data.Length);
stm.Flush();
//MessageBox.Show("Data Sent, length = " + data.Length.ToString());
}
else
{
MessageBox.Show("Either we are not connected, or there is no data to send!!");
}
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
public void ReadAllBytes()
{
try
{
// Buffer to store the response bytes.
Byte[] readdata = new Byte[256];
// String to store the response ASCII representation.
String responseData = String.Empty;
NetworkStream stm = m_client.GetStream();
// Read the first batch of the TcpServer response bytes.
Int32 bytes = stm.Read(readdata, 0, readdata.Length);
responseData = Encoding.ASCII.GetString(readdata, 0, bytes);
SingleReplyRichTextBox.Text += responseData + "\r\n";
}
catch (Exception err)
{
MessageBox.Show(err.ToString());
}
}
Does anything in here raise a red flag that is obvious? I tried Stream VS NetworkStream. I tried turning off the Reply listener. I took this code and combined it all into one function, and moved the TcpClient creation over to a different Class as static so I could create it in each function, but while all of these worked fine locally, nothing works connecting to office. It won't send a single byte. I set m_client as static at the top too, works fine locally, not to office.
Is GetStream failing maybe? or its sending the data on a different socket?
use a Task and cancellation token to cancel the task. Don't init a "new" TCPclient. In the background the TCPclient will be not closed (socket-timeout of .net)
Use try catches to see the exception and add the log to the conversation to make it more clear pls

While true loop not infinite?

So I am making a bot that connects to a twitch irc chat. Here is the code:
Console.WriteLine("Joining Room");
IrcClient irc = new IrcClient("irc.twitch.tv", 6667, "ScottBots", "oauth:asdasd");
irc.joinRoom("ScottBots");
Console.WriteLine("Joined Room");
int i = 0;
while (true)
{
string message = irc.readMessage();
if(message.Contains("!helps"))
{
irc.sendChatMessage("Welcome to ScottBots! Currently in development.");
}
Console.WriteLine("loop: " + i);
i++;
}
Look the the while true loop... Everything good?
Now look at what this console application gives me:
Joining Room
Joined Room
loop: 0
loop: 1
loop: 2
loop: 3
loop: 4
loop: 5
loop: 6
loop: 7
loop: 8
loop: 9
It just stops at 9?
Many of ya'll have been asking for my ircClient Code:
private string username;
private string channel;
private TcpClient tcpClient;
private StreamReader inputStream;
private StreamWriter outputSteam;
public IrcClient(string ip, int port, string username, string password)
{
this.username = username;
tcpClient = new TcpClient(ip, port);
inputStream = new StreamReader(tcpClient.GetStream());
outputSteam = new StreamWriter(tcpClient.GetStream());
try
{
outputSteam.WriteLine("PASS " + password);
outputSteam.WriteLine("NICK " + username);
outputSteam.WriteLine("USER " + username + " 8 * :" + username);
outputSteam.Flush();
} catch (Exception e)
{
}
}
public void joinRoom(string channel)
{
try
{
this.channel = channel;
outputSteam.WriteLine("JOIN #" + channel);
outputSteam.Flush();
}
catch (Exception e)
{
Console.WriteLine("Failed to join room");
}
}
public void sendIrcMessage(string message)
{
try
{
outputSteam.WriteLine(message);
outputSteam.Flush();
}
catch (Exception e)
{
Console.WriteLine("failed to run sendIrcMessage() method");
}
}
public void sendChatMessage(string message)
{
sendIrcMessage(":" + username + "!" + username + "#" + username + ".tmi.twitch.tv PRIVNSG #" + channel + " : " + message);
}
public string readMessage()
{
string message = inputStream.ReadLine();
return message;
}
It looks like one of irc.SendChatMessage() or irc.ReadMessage() is blocking, perhaps when it runs out of buffered input/output and needs to wait on the socket.
EDIT: Almost certainly the irc.ReadMessage() call is blocking. It's calling ReadLine() against a Stream which is in turn linked to a TcpClient. You probably want to look into either threading and/or asynchronous callbacks if you want to build an IRC bot and test rig. Here's an example (not IRC-related): http://sunildube.blogspot.ca/2011/12/asynchronous-tcp-client-easy-example.html

An attempt was made to access a socket in a way forbidden by its access permissions, what to do? [duplicate]

This question already has answers here:
C# Socket Exception : an attempt was made to access a socket in a way forbidden by its access permissions
(2 answers)
Closed 7 years ago.
i am working on a school project. i am trying to make a sniffer.
in school the project works but in my house there is a problem.
this is the exception it throws me:"An attempt was made to access a socket in a way forbidden by its access permissions"
this is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
namespace MJsniffer
{
public enum Protocol
{
TCP = 6,
UDP = 17,
Unknown = -1
};
public partial class MJsnifferForm : Form
{
private Socket mainSocket; //The socket which captures all incoming packets
private byte[] byteData = new byte[4096];
private bool bContinueCapturing = false; //A flag to check if packets are to be captured or not
private delegate void AddTreeNode(TreeNode node);
public MJsnifferForm()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
if (cmbInterfaces.Text == "")
{
MessageBox.Show("Select an Interface to capture the packets.", "MJsniffer",
MessageBoxButtons.OK, MessageBoxIcon.Error); //THIS IS WHERE THE PROBLEM IS.
return;
}
try
{
if (!bContinueCapturing)
{
//Start capturing the packets...
btnStart.Text = "&Stop";enter code here
bContinueCapturing = true;
//For sniffing the socket to capture the packets has to be a raw socket, with the
//address family being of type internetwork, and protocol being IP
mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Raw, ProtocolType.IP);
//Bind the socket to the selected IP address
mainSocket.Bind(new IPEndPoint(IPAddress.Parse(cmbInterfaces.Text), 0));
//Set the socket options
mainSocket.SetSocketOption(SocketOptionLevel.IP, //Applies only to IP packets
SocketOptionName.HeaderIncluded, //Set the include the header
true); //option to true
byte[] byTrue = new byte[4] {1, 0, 0, 0};
byte[] byOut = new byte[4]{1, 0, 0, 0}; //Capture outgoing packets
//Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
mainSocket.IOControl(IOControlCode.ReceiveAll, //Equivalent to SIO_RCVALL constant
//of Winsock 2
byTrue,
byOut);
//Start receiving the packets asynchronously
mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), null);
}
else
{
btnStart.Text = "&Start";
bContinueCapturing = false;
//To stop capturing the packets close the socket
mainSocket.Close ();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "MJsniffer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OnReceive(IAsyncResult ar)
{
try
{
int nReceived = mainSocket.EndReceive(ar);
//Analyze the bytes received...
ParseData (byteData, nReceived);
if (bContinueCapturing)
{
byteData = new byte[4096];
//Another call to BeginReceive so that we continue to receive the incoming
//packets
mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), null);
}
}
catch (ObjectDisposedException)
{
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "MJsniffer", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ParseData(byte[] byteData, int nReceived)
{
TreeNode rootNode = new TreeNode();
//Since all protocol packets are encapsulated in the IP datagram
//so we start by parsing the IP header and see what protocol data
//is being carried by it
IPHeader ipHeader = new IPHeader(byteData, nReceived);
TreeNode ipNode = MakeIPTreeNode(ipHeader);
rootNode.Nodes.Add(ipNode);
//Now according to the protocol being carried by the IP datagram we parse
//the data field of the datagram
switch (ipHeader.ProtocolType)
{
case Protocol.TCP:
TCPHeader tcpHeader = new TCPHeader(ipHeader.Data, //IPHeader.Data stores the data being
//carried by the IP datagram
ipHeader.MessageLength);//Length of the data field
TreeNode tcpNode = MakeTCPTreeNode(tcpHeader);
rootNode.Nodes.Add(tcpNode);
//If the port is equal to 53 then the underlying protocol is DNS
//Note: DNS can use either TCP or UDP thats why the check is done twice
if (tcpHeader.DestinationPort == "53" || tcpHeader.SourcePort == "53")
{
TreeNode dnsNode = MakeDNSTreeNode(tcpHeader.Data, (int)tcpHeader.MessageLength);
rootNode.Nodes.Add(dnsNode);
}
break;
case Protocol.UDP:
UDPHeader udpHeader = new UDPHeader(ipHeader.Data, //IPHeader.Data stores the data being
//carried by the IP datagram
(int)ipHeader.MessageLength);//Length of the data field
TreeNode udpNode = MakeUDPTreeNode(udpHeader);
rootNode.Nodes.Add(udpNode);
//If the port is equal to 53 then the underlying protocol is DNS
//Note: DNS can use either TCP or UDP thats why the check is done twice
if (udpHeader.DestinationPort == "53" || udpHeader.SourcePort == "53")
{
TreeNode dnsNode = MakeDNSTreeNode(udpHeader.Data,
//Length of UDP header is always eight bytes so we subtract that out of the total
//length to find the length of the data
Convert.ToInt32(udpHeader.Length) - 8);
rootNode.Nodes.Add(dnsNode);
}
break;
case Protocol.Unknown:
break;
}
AddTreeNode addTreeNode = new AddTreeNode(OnAddTreeNode);
rootNode.Text = ipHeader.SourceAddress.ToString() + "-" +
ipHeader.DestinationAddress.ToString();
//Thread safe adding of the nodes
treeView.Invoke(addTreeNode, new object[] {rootNode});
}
//Helper function which returns the information contained in the IP header as a
//tree node
private TreeNode MakeIPTreeNode(IPHeader ipHeader)
{
TreeNode ipNode = new TreeNode();
ipNode.Text = "IP";
ipNode.Nodes.Add ("Ver: " + ipHeader.Version);
ipNode.Nodes.Add ("Header Length: " + ipHeader.HeaderLength);
ipNode.Nodes.Add ("Differntiated Services: " + ipHeader.DifferentiatedServices);
ipNode.Nodes.Add("Total Length: " + ipHeader.TotalLength);
ipNode.Nodes.Add("Identification: " + ipHeader.Identification);
ipNode.Nodes.Add("Flags: " + ipHeader.Flags);
ipNode.Nodes.Add("Fragmentation Offset: " + ipHeader.FragmentationOffset);
ipNode.Nodes.Add("Time to live: " + ipHeader.TTL);
switch (ipHeader.ProtocolType)
{
case Protocol.TCP:
ipNode.Nodes.Add ("Protocol: " + "TCP");
break;
case Protocol.UDP:
ipNode.Nodes.Add ("Protocol: " + "UDP");
break;
case Protocol.Unknown:
ipNode.Nodes.Add ("Protocol: " + "Unknown");
break;
}
ipNode.Nodes.Add("Checksum: " + ipHeader.Checksum);
ipNode.Nodes.Add("Source: " + ipHeader.SourceAddress.ToString());
ipNode.Nodes.Add("Destination: " + ipHeader.DestinationAddress.ToString());
return ipNode;
}
//Helper function which returns the information contained in the TCP header as a
//tree node
private TreeNode MakeTCPTreeNode(TCPHeader tcpHeader)
{
TreeNode tcpNode = new TreeNode();
tcpNode.Text = "TCP";
tcpNode.Nodes.Add("Source Port: " + tcpHeader.SourcePort);
tcpNode.Nodes.Add("Destination Port: " + tcpHeader.DestinationPort);
tcpNode.Nodes.Add("Sequence Number: " + tcpHeader.SequenceNumber);
if (tcpHeader.AcknowledgementNumber != "")
tcpNode.Nodes.Add("Acknowledgement Number: " + tcpHeader.AcknowledgementNumber);
tcpNode.Nodes.Add("Header Length: " + tcpHeader.HeaderLength);
tcpNode.Nodes.Add("Flags: " + tcpHeader.Flags);
tcpNode.Nodes.Add("Window Size: " + tcpHeader.WindowSize);
tcpNode.Nodes.Add("Checksum: " + tcpHeader.Checksum);
if (tcpHeader.UrgentPointer != "")
tcpNode.Nodes.Add("Urgent Pointer: " + tcpHeader.UrgentPointer);
return tcpNode;
}
//Helper function which returns the information contained in the UDP header as a
//tree node
private TreeNode MakeUDPTreeNode(UDPHeader udpHeader)
{
TreeNode udpNode = new TreeNode();
udpNode.Text = "UDP";
udpNode.Nodes.Add("Source Port: " + udpHeader.SourcePort);
udpNode.Nodes.Add("Destination Port: " + udpHeader.DestinationPort);
udpNode.Nodes.Add("Length: " + udpHeader.Length);
udpNode.Nodes.Add("Checksum: " + udpHeader.Checksum);
return udpNode;
}
//Helper function which returns the information contained in the DNS header as a
//tree node
private TreeNode MakeDNSTreeNode(byte[] byteData, int nLength)
{
DNSHeader dnsHeader = new DNSHeader(byteData, nLength);
TreeNode dnsNode = new TreeNode();
dnsNode.Text = "DNS";
dnsNode.Nodes.Add("Identification: " + dnsHeader.Identification);
dnsNode.Nodes.Add("Flags: " + dnsHeader.Flags);
dnsNode.Nodes.Add("Questions: " + dnsHeader.TotalQuestions);
dnsNode.Nodes.Add("Answer RRs: " + dnsHeader.TotalAnswerRRs);
dnsNode.Nodes.Add("Authority RRs: " + dnsHeader.TotalAuthorityRRs);
dnsNode.Nodes.Add("Additional RRs: " + dnsHeader.TotalAdditionalRRs);
return dnsNode;
}
private void OnAddTreeNode(TreeNode node)
{
treeView.Nodes.Add(node);
}
private void SnifferForm_Load(object sender, EventArgs e)
{
string strIP = null;
IPHostEntry HosyEntry = Dns.GetHostEntry((Dns.GetHostName()));
if (HosyEntry.AddressList.Length > 0)
{
foreach (IPAddress ip in HosyEntry.AddressList)
{
strIP = ip.ToString();
cmbInterfaces.Items.Add(strIP);
}
}
}
private void SnifferForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (bContinueCapturing)
{
mainSocket.Close();
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
//MessageBox.Show(comboBox1.SelectedItem.ToString());
}
private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
}
private void treeView2_AfterSelect(object sender, TreeViewEventArgs e)
{
}
}
}
You are required to have administrator rights in order to use raw sockets. Apparently, you aren't running this code under an account with administrator rights.
To fix this, run the code under an account with administrator rights.

Using TcpListener.AcceptSocket(); in a separate thread causes the thread to block?

I have tried to work around this as well as debug but I'm at a loose end here :( is there any alternative to using this to check for a client connection? This code works fine in a console application so i am guessing the thread is being blocked, although it may be something else i can't see?
public partial class Form1 : Form
{
Socket s;
Declatation of socket.
private void startButton_Click(object sender, EventArgs e)
{
checkTimer.Enabled = true;
if (bw.IsBusy != true)
{
bw.RunWorkerAsync();
}
}
Background thread to start on button press.
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
working();
}
Thread runs the "working" method.
private void working()
{
if (threadFirstRun == true)
{
threadFirstRun = false;
}
try
{
String tempAddr = tbAddr.Text;
IPAddress ipAd = IPAddress.Parse("147.197.204.172");
// use local m/c IP address, and
// use the same in the client
String tempPort = tbPort.Text;
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 3000);
/* Start Listeneting at the specified port */
myList.Start();
tcConnection1 = "Console:\n" + "The server is running at port 3000...";
tcConnection2 = "\n" + "The local End point is :" + myList.LocalEndpoint;
tcConnection3 = "\n" + "Waiting for a connection.....";
while (true)
{
s = myList.AcceptSocket();
if (s != null)
{
if (connectionEstab == false)
{
tcEstab = "\n" + "Connection accepted from " + s.RemoteEndPoint;
connectionEstab = true;
}
byte[] b = new byte[100];
int k = s.Receive(b);
//Console.WriteLine("Recieved...");
for (int i = 0; i < k; i++)
{
//Console.Write(Convert.ToChar(b[i]));
tcValue = tcValue + Convert.ToString(b[i]);
valueArray[ii] = (float)Convert.ToDouble(b[i]);
}
tcValue = tcValue + "\n";
ii++;
}
else
{
Thread.Sleep(200);
}
}
ASCIIEncoding asen = new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
rtbConsole.Text = rtbConsole.Text + "\n" + "Sent Acknowledgement";
/* clean up */
s.Close();
myList.Stop();
}
catch (Exception ex)
{
tcError = "\n\n" + "Error..... " + ex.StackTrace;
}
}
Working method starts the server and blocks upon calling myList.AcceptSocket();?
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
rtbConsole.Text = rtbConsole.Text + "\n" + "Canceled!";
}
else if (!(e.Error == null))
{
rtbConsole.Text = rtbConsole.Text + "\n\n" + ("Error: " + e.Error.Message);
}
else
{
rtbConsole.Text = rtbConsole.Text + "\n" + "Done!";
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
rtbConsole.Text = rtbConsole.Text + "\n" + (e.ProgressPercentage.ToString() + "%");
}
private void stopButton_Click(object sender, EventArgs e)
{
checkTimer.Enabled = false;
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync();
}
}
Other methods for some completeness.
Sending data from my android device is received by a console app running 1 thread, however nothing seems to happen in this windows form application upon sending data to the same ip and port from the same program on the same device. The separate thread just stays blocked and the android app cannot complete communication to send the data.
It's supposed to block. It can never return null. (Why is everybody doing this? It's like nobody on the web uses Accept correctly.)
Your problem is that after accepting one connection you process that connection and do nothing to resume accepting. The standard pattern is:
while (true) {
var connectionSocket = listeningSocket.Accept();
ProcessAsynchronously(connectionSocket);
}
Make sure ProcessAsynchronously returns immediately. Start a new Task or use async/await.
As you never exit the while loop you never get to sending data. Move all processing logic into ProcessAsynchronously.
It is supposed to block. From MSDN:
AcceptSocket is a blocking method that returns a Socket that you can
use to send and receive data. If you want to avoid blocking, use the
Pending method to determine if connection requests are available in
the incoming connection queue.
You can turn your whole implementation to use the async version: AcceptSocketAsync. Note this wont block your method, it will yield control back to the caller until a new Socket has been connected.
private async void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
await WorkingAsync();
}
And inside WorkingAsync:
private Task WorkingAsync
{
// Do all other stuff,
Socket socket = await myList.AcceptSocketAsync();
// Do rest of stuff with the socket
}
I recommend you like at What is the async/await equivalent of a ThreadPool server? for a full implementation of an async tcp connection handler

How to send a reply message to sender machine via serial port using c#

I am using the below code to receive the message via serial port which is working fine. Now i need to send back a acknowledgment message to the sender machine. How can send the message ?
private void MonitorSP_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
System.IO.Ports.SerialPort SP = (System.IO.Ports.SerialPort)sender;
//Get the ports available in system
string[] theSerialPortNames = System.IO.Ports.SerialPort.GetPortNames();
string strAvlPortNames = "";
foreach (string s in theSerialPortNames)
{
strAvlPortNames += s.ToString() + ", ";
}
//Read an contruct the message
Thread.Sleep(1000);
string msg = SP.ReadExisting();
string ConstructedMsg = "Port's Found : " + strAvlPortNames + "\n" + "Port Used : " + SP.PortName + "\n" + "Message Received : " + msg;
if (InvokeRequired)
{
richTextBox1.Invoke(new MethodInvoker(delegate { richTextBox1.Text = ConstructedMsg; }));
//Send acknowlegement to sender port
SP.Write(SP.PortName);
return;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.StackTrace.ToString());
}
}
You are already calling SP.Write(), that ought to be close. Although you probably don't want to send the port name back, the sender has little use for that. It also shouldn't be in the InvokeRequired test. Which is always true btw, you might as well remove that.
You also really want to get rid of the Sleep() call. Use ReadLine() if the sender terminates its message with a line feed ("\n"). If you are contemplating this because you need the sender to stop sending until it gets the acknowledgment then the real problem is in you using Sleep and ReadExisting.

Categories