I have been following an old tutorial for making a chat program and I have been dissecting it to fit into a new form, although I have gotten it to work as it was intended it runs into the error: "Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCall."
that points to this part of the code.
while (Connected)
{
// Show the messages in the log TextBox
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
}
I only get the error upon closing the client, or disconnecting.
this is the majority of the client code.
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;
using System.IO;
namespace Table_Top_RPG
{
public partial class Connect : Form
{
// Will hold the user name
private string UserName = "Unknown";
public static StreamWriter swSender;
private StreamReader srReceiver;
private TcpClient tcpServer;
// Needed to update the form with messages from another thread
private delegate void UpdateLogCallback(string strMessage);
// Needed to set the form to a "disconnected" state from another thread
private delegate void CloseConnectionCallback(string strReason);
private Thread thrMessaging;
private IPAddress ipAddr;
private bool Connected;
public Connect()
{
// On application exit, don't forget to disconnect first
Application.ApplicationExit += new EventHandler(OnApplicationExit);
InitializeComponent();
}
private void BtnConnect_Click(object sender, EventArgs e)
{
// If we are not currently connected but awaiting to connect
if (Connected == false)
{
InitializeConnection();
}
else // We are connected, thus disconnect
{
CloseConnection("Disconnected at user's request.");
}
}
// The event handler for application exit
public void OnApplicationExit(object sender, EventArgs e)
{
if (Connected == true)
{
// Closes the connections, streams, etc.
Connected = false;
swSender.Close();
srReceiver.Close();
tcpServer.Close();
}
}
private void InitializeConnection()
{
// Parse the IP address from the TextBox into an IPAddress object
ipAddr = IPAddress.Parse(Connect.IpBox.Text);
// Start a new TCP connections to the chat server
tcpServer = new TcpClient();
tcpServer.Connect(ipAddr, int.Parse(Connect.PortBox.Text));
// Helps us track whether we're connected or not
Connected = true;
// Prepare the form
UserName = Connect.NameBox.Text;
// Disable and enable the appropriate fields
IpBox.Enabled = false;
NameBox.Enabled = false;
Main.TxtMsg.Enabled = true;
Connect.BtnConnect.Text = "Disconnect";
// Send the desired username to the server
swSender = new StreamWriter(tcpServer.GetStream());
swSender.WriteLine(UserName);
swSender.Flush();
// Start the thread for receiving messages and further communication
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
}
private void ReceiveMessages()
{
// Receive the response from the server
srReceiver = new StreamReader(tcpServer.GetStream());
// If the first character of the response is 1, connection was successful
string ConResponse = srReceiver.ReadLine();
// If the first character is a 1, connection was successful
if (ConResponse[0] == '1')
{
// Update the form to tell it we are now connected
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connected Successfully!" });
}
else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
{
string Reason = "Not Connected: ";
// Extract the reason out of the response message. The reason starts at the 3rd character
Reason += ConResponse.Substring(2, ConResponse.Length - 2);
// Update the form with the reason why we couldn't connect
this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
// Exit the method
return;
}
// While we are successfully connected, read incoming lines from the server
while (Connected)
{
// Show the messages in the log TextBox
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
}
}
internal void CloseConnection(string Reason)
{
// Show the reason why the connection is ending
Main.ChatLog.AppendText(Reason + "\r\n");
// Enable and disable the appropriate controls on the form
IpBox.Enabled = true;
NameBox.Enabled = true;
Main.TxtMsg.Enabled = false;
BtnConnect.Text = "Connect";
// Close the objects
Connected = false;
swSender.Close();
srReceiver.Close();
tcpServer.Close();
}
// This method is called from a different thread in order to update the log TextBox
private void UpdateLog(string strMessage)
{
// Append text also scrolls the TextBox to the bottom each time
Main.ChatLog.AppendText(strMessage + "\r\n");
}
}
}
there is another form called Main where all the chat dialog is sent, but the majority of its code is not relevant.
if anyone knows a better way to handle this or knows of a good chat program tutorial i can go through for better examples of how clients connect and disconnect is handled properly without crashing I would be much appreciative.