Hallo zusammen,
ich habe einen kleinen TCP-Server und einen -Client erstellt.
Der nachfolgende Quellcode zeigt den Client, dessen Form aus den folgenden
Steuerelementen besteht:
using System;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace TCPClientTest
{
// ---------------------------------------------------------------------------------
// Form
// ---------------------------------------------------------------------------------
public partial class MainWindow : Form
{
// --------------------------------------------------------------------------------
// Declarations
// --------------------------------------------------------------------------------
// IP Address and Port
private IPAddress ipAddress;
private int port;
// TCP Client
private TcpClient tcpClient;
private NetworkStream stream;
// --------------------------------------------------------------------------------
// Declarations
// --------------------------------------------------------------------------------
// Form
// --------------------------------------------------------------------------------
// Form: Constructor
public MainWindow()
{
InitializeComponent();
}
// Form: Load
private void MainWindow_Load(object sender, EventArgs e)
{
// Fill ComboBox of IP Address
cmb_IPAddress.Items.Add("Loopback");
IPHostEntry hostInfo = Dns.GetHostByName(Dns.GetHostName());
for(int i = 0; i < hostInfo.AddressList.Length; i++)
{
cmb_IPAddress.Items.Add(hostInfo.AddressList[i].ToString());
}
cmb_IPAddress.SelectedIndex = 0;
}
// Form: Closed
private void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
{
stream.Close();
tcpClient.Close();
}
// --------------------------------------------------------------------------------
// Controls
// --------------------------------------------------------------------------------
// Button: Connect
private void btn_Connect_Click(object sender, EventArgs e)
{
// Detect IP Address and Port
if (cmb_IPAddress.Text == "Loopback")
{
ipAddress = IPAddress.Loopback;
}
else
{
ipAddress = IPAddress.Parse(cmb_IPAddress.Text);
}
port = Convert.ToInt32(txt_Port.Text);
// Send data
tcpClient = new TcpClient();
tcpClient.Connect(ipAddress, port);
stream = tcpClient.GetStream();
byte[] msgBytArr = Encoding.ASCII.GetBytes(txt_SendText.Text);
stream.Write(msgBytArr, 0, msgBytArr.Length);
}
}
}
Soweit funktioniert auch alles, der TCP-Server empfängt die Daten und zeigt diese auch korrekt an.
Mein Problem ist, daß ich mit einem zusätzlichen Button die Funktionen zum Verbinden des TCP-Client und dem Senden der Daten trennen möchte, um nicht bei jedem Sendevorgang einen neuen TCP-Client erzeugen zu müßen.
Dazu habe ich einen zusätzlichen "Send"-Button eingefügt, und Code-Teile des Buttons "Connect" dorthin ausgelagert.
Der "Controls"-Bereich des neuen Quellcodes sieht somit folgendermaßen aus:
// --------------------------------------------------------------------------------
// Controls
// --------------------------------------------------------------------------------
// Button: Connect
private void btn_Connect_Click(object sender, EventArgs e)
{
// Detect IP Address and Port
if (cmb_IPAddress.Text == "Loopback")
{
ipAddress = IPAddress.Loopback;
}
else
{
ipAddress = IPAddress.Parse(cmb_IPAddress.Text);
}
port = Convert.ToInt32(txt_Port.Text);
// Send data
tcpClient = new TcpClient();
tcpClient.Connect(ipAddress, port);
stream = tcpClient.GetStream();
}
// Button: Send
private void btn_Send_Click(object sender, EventArgs e)
{
byte[] msgBytArr = Encoding.ASCII.GetBytes(txt_SendText.Text);
stream.Write(msgBytArr, 0, msgBytArr.Length);
}
}
}
Bei Ausführen bekomme ich allerdings den folgenden Effekt:
Der TCP-Client läßt sich mit dem Server verbinden.
Beim 1. Klick auf den "Send"-Button wird der Text korrekt vom Server empfangen.
Beim 2. Klick auf den "Send"-Button zeigt der TCP-Server keine Rekation mehr.
Beim 3. Klick auf den "Send"-Button wird der folgende Fehler ausgelöst:
"In die Übertragungsverbindung können keine Daten geschrieben werden: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen."
Kann mir jemand eine Tipp geben, wo der Fehler zu suchen ist?
Vielen Dank und viel Grüße
Frank
Nach dem Fehler zu urteilen stürzt der Server entweder beim 2. Datenempfang ab oder aber bekommt schon den 2. Datenempfang nicht.
Die Meldung nach dem 3. Senden weist darauf hin, dass der Server tatsächlich die Arbeit eingestellt hat.
Wissen ist nicht alles. Man muss es auch anwenden können.
PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |
Also im Endeffekt solltest Du den gesamten Code neu schreiben.
Dass Du die gesamte Kommunikationslogik direkt in die UI wirfst ist natürlich alles andere als günstig und gut.
[Artikel] Drei-Schichten-Architektur
Kannst Dir entsprechend Events erstellen, dass Du nicht immer und immer wieder den gleichen Code schreiben musst.
Ansonsten kannst Du solche Symptome eigentlich gut debuggen
[Artikel] Debugger: Wie verwende ich den von Visual Studio?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code