Ho un'applicazione che ho scritto per la mia applicazione distribuita in tutta l'azienda per l'invio di dati tramite il nostro server Windows 2003 (con IIS 6.0 in esecuzione). Messaggi di testo di dimensioni ridotte, ma i messaggi più grandi contenenti più dati (circa 20 KB) non riescono a passare.Connessione client TCP
Imposta il buffer di byte sulla dimensione del buffer del client TCP. Ho notato che i miei dati venivano ricevuti sul server; tuttavia, ha eseguito il looping della routine di ricezione solo una volta e i miei file di grandi dimensioni avevano sempre esattamente la dimensione della dimensione del buffer o 8 KB sul nostro server. In altre parole, il mio codice esegue solo un ciclo prima che il server chiuda la connessione socket.
Pensando che potrebbe esserci un problema con il riempimento dell'intero buffer, ho provato a limitare le mie letture/scritture a solo 1 KB, ma questo ha provocato il nostro server chiudere il socket dopo aver ricevuto 1 KB prima di chiudere la connessione.
Invio il messaggio di errore del server al client in modo che possa visualizzarlo. Il messaggio di errore specifico che ricevo dal client è:
“Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.”
ho aggiornato il mio applicazione server in modo che il socket TCP sottostante avrebbe usato “keep alive” con questa linea:
client.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
Ora, ogni volta tento di inviare un messaggio, il cliente riceve l'errore:
“Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.”
amministratore nostra rete mi ha detto che non ha un firewall o qualsiasi porte bloccate sul nostro server interno.
Cerca su Google gli errori, ho trovato post che suggeriscono che le persone provano a telnet nel server. Ho usato le loro direzioni al telnet al server, ma non sono sicuro di cosa fare della risposta:
C:> telnet Welcome to Microsoft Telnet Client
Escape Character is ‘CTRL+]’
Microsoft Telnet> open cpapp 500 Connecting To cpapp…
Questo è tutto quello che ricevo. Non ricevo mai un errore, e lo schermo Telnet di Microsoft cambierà in "Premere un tasto qualsiasi per continuare ..." - Immagino che vada in timeout, ma il mio codice è in qualche modo in grado di connettersi.
Ho provato altre porte in codice e tramite Telnet compresi 25, 80 e 8080. Telnet ha rilasciato la porta 25, ma la mia applicazione sembra leggere il primo ciclo, non importa quale porta gli dica di eseguire.
Ecco il mio codice che viene eseguito sul client:
int sendUsingTcp(string location) {
string result = string.Empty;
try {
using (FileStream fs = new FileStream(location, FileMode.Open, FileAccess.Read)) {
using (TcpClient client = new TcpClient(GetHostIP, CpAppDatabase.ServerPortNumber)) {
byte[] riteBuf = new byte[client.SendBufferSize];
byte[] readBuf = new byte[client.ReceiveBufferSize];
using (NetworkStream ns = client.GetStream()) {
if ((ns.CanRead == true) && (ns.CanWrite == true)) {
int len;
string AOK = string.Empty;
do {
len = fs.Read(riteBuf, 0, riteBuf.Length);
ns.Write(riteBuf, 0, len);
int nsRsvp = ns.Read(readBuf, 0, readBuf.Length);
AOK = Encoding.ASCII.GetString(readBuf, 0, nsRsvp);
} while ((len == riteBuf.Length) && (-1 < AOK.IndexOf("AOK")));
result = AOK;
return 1;
}
return 0;
}
}
}
} catch (Exception err) {
Logger.LogError("Send()", err);
MessageBox.Show(err.Message, "Message Failed", MessageBoxButtons.OK, MessageBoxIcon.Hand, 0);
return -1;
}
}
Ecco il mio codice che viene eseguito sul server:
SvrForm.Server = new TcpListener(IPAddress.Any, CpAppDatabase.ServerPortNumber);
void Worker_Engine(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), Application.CompanyName);
if (Directory.Exists(path) == false) Directory.CreateDirectory(path);
Thread.Sleep(0);
string eMsg = string.Empty;
try {
SvrForm.Server.Start();
do {
using (TcpClient client = SvrForm.Server.AcceptTcpClient()) { // waits until data is avaiable
if (worker.CancellationPending == true) return;
client.Client.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.KeepAlive, true);
string location = Path.Combine(path, string.Format("Acp{0:yyyyMMddHHmmssff}.bin", DateTime.Now));
byte[] buf = new byte[client.ReceiveBufferSize];
try {
using (NetworkStream ns = client.GetStream()) {
if ((ns.CanRead == true) && (ns.CanWrite == true)) {
try {
int len;
byte[] AOK = Encoding.ASCII.GetBytes("AOK");
using (FileStream fs = new FileStream(location, FileMode.Create, FileAccess.Write)) {
do {
len = ns.Read(buf, 0, client.ReceiveBufferSize);
fs.Write(buf, 0, len);
ns.Write(AOK, 0, AOK.Length);
} while ((0 < len) && (ns.DataAvailable == true));
}
byte[] okBuf = Encoding.ASCII.GetBytes("Message Received on Server");
ns.Write(okBuf, 0, okBuf.Length);
} catch (Exception err) {
Global.LogError("ServerForm.cs - Worker_Engine(DoWorkEvent)", err);
byte[] errBuf = Encoding.ASCII.GetBytes(err.Message);
ns.Write(errBuf, 0, errBuf.Length);
}
}
}
}
worker.ReportProgress(1, location);
}
} while (worker.CancellationPending == false);
} catch (SocketException) {
// See MSDN: Windows Sockets V2 API Error Code Documentation for detailed description of error code
e.Cancel = true;
} catch (Exception err) {
eMsg = "Worker General Error:\r\n" + err.Message;
e.Cancel = true;
e.Result = err;
} finally {
SvrForm.Server.Stop();
}
}
Perché lo domanda Continua la lettura da parte del Cliente TCP ? Ho dimenticato di impostare qualcosa che dice allo Socket di rimanere aperto finché non ho finito? Il codice server non vede mai un'eccezione perché il Client TCP non viene mai fermato, quindi so che non ci sono errori.
Il nostro amministratore di rete non ha ancora ricevuto la sua laurea, quindi se si scopre che si tratta di un problema con il server, vi preghiamo di fornire una descrizione dettagliata su come risolverlo, perché potremmo non capire quello che state dicendo .
Mi scuso per il fatto che sia così lungo, ma voglio essere sicuro che la gente là fuori sappia cosa sto facendo - e forse anche qualche informazione dalla mia tecnica!
Grazie per l'aiuto! ~ Joe
No scherzo? Immagino che abbia senso ora. Continuavo a pensare che qualcosa doveva essere configurato sul server. Questo aiuta un * sacco *! Grazie! – jp2code
come lo farei? "precedere il contenuto inviato con la lunghezza di quel contenuto" non ho la lunghezza del contenuto inviato? –
Se non si conosce la lunghezza, ovviamente non si invia la lunghezza sul filo. – Amy