Gå til innhold

Klient / server applikasjon, et lite problem..


Anbefalte innlegg

Hei!

 

Jeg driver å lager et lite program som skal sende litt info over nettverket:)

 

Programmet bygger på koden som dere kan finne her..

 

Så til problemet. Når klienten skal logge på serveren skal det sendes litt informasjon til klienten, dette gjøres ved å sende korte tekster til klienten. Men hvis serveren bare skal pøse på med disse små tekstene klarer ikke klienten å fange opp all informasjonen. Jeg vil derfor at klienten skal si at den er klar til å ta imot den neste teksten. Er det da mulig å få serveren til å gjøre dette? Tråden må jo settes på pause eller noe liknende før den neste teksten sendes. Kan en tråd vente på at noe skal skje før den fortsetter? Feks, ved en loop eller liknende..

 

Dette ble en meget rar forklaring, håper noen av dere får noe ut av dette.

Er takknemlig for alle svar som kan bidra til at problemet løses:)

 

Hilsen Eirik

Lenke til kommentar
Videoannonse
Annonse

Hvordan mener du?

 

TCP har flow control innebygget i protokollen, så om du bruker en korrekt TCP implementasjon, f.eks System.Net.Sockets.TcpClient, i begge ender er det allerede i orden.

 

Da er det ikke mulig å skrive fortere enn mottaker klarer å lese. read/write operasjoner vil da blokkere til data blir sendt/lest riktig, evt. kaste exception hvis noe går galt.

 

Edit: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Flow_control

Endret av MailMan13
Lenke til kommentar

ja, bruker System.Net.Sockets.TcpClient i begge ender, da vil det si at klienten mottar alle dataene riktig.

 

Hvis du ser på koden som jeg linket til over ser du at klienten sender dataene den mottar fra serveren til en ny tråd ( MessageReceived ) Der har jeg lagt inn ganske mye koder, feks, lagre mottatt melding som tekstfil. vil dette da være en flaskekork at denne tråden ikke rekker å utføre alle funkjoner før den blir bedt om å gjøre det en gang til?

 

kan dette løses ved at MessageReceived sender dataene til en BackgroundWorker eller liknende som lagrer filene på den lokale disken i stede for at MessageReceived gjør det?

 

Nok en lang forklaring :)

Lenke til kommentar

Du trenger ikke gjøre noen ting, uansett hvor lang tid det tar på klienten.

 

Transportlaget (TCP protokollen) tar seg av throttling av sendingen, det ikke mulig å sende "for mye" eller "for fort" over en slik tilkobling.

 

Hvis det går for sakte på klienten, slik at read-bufferet TCPClient blir fullt, sier den ifra selv til mottaker at den ikke kan ta imot mer, så holder den igjen. Det er innebygget i TCP protokollen og ikke noe vi programmerer selv.

 

Tror du misforstår litt hvordan TCPClient fungerer. Data kan mottas når som helst når forbindelsen er åpnet, dem legges så i input-bufferet når noe kommer inn. Det er ikke Read() metoden tar imot data direkte over nettverket, den bare leser det neste fra bufferet. Siden vi bruker TCP er vi da garantert at det neste vi leser fra bufferet alltid er korrekt, fullstendig og i riktig rekkefølge.

Endret av MailMan13
Lenke til kommentar

Linjene som sendes er feks:

 

/Melding|sender|melding

 

disse linjene deles opp ved string.spilt komandoen

 

har innimellom merket at linjene henger sammen når ting sendes for fort da går det sånn:

 

/Melding|sender|melding/Melding|sender|melding

 

kan grunnen være at de kommer på samme linje og at split kommandoen bare oppfatter starten av linjen og at den ikke leser siste delen av linjen?

 

dvs. meldingen kommer fram, men brukeren får ikke vist den siste meldingen.

 

hvis det er dette som er feil, er det noen som har en god forklaring på hvordan dette kan endres?

Lenke til kommentar

Det virker som du forventer at du skal få til å lage 1:1 forhold mellom det som sendes med write() på ene siden og det som leses med read() på den andre?

 

Slik er det ikke, selv om det kan virke slik når vi tester i kontrollerte former. I praksis kan du aldri stole på at det er slik, underliggende nettverksprotokoller kan dele opp pakkene dine og sette dem sammen som dem vil. Det ser ut som du leser alt som ligger i bufferet og så antar at det er èn og bare èn melding der. Det kan være både flere meldinger, og deler av meldinger om dem er blitt delt opp på veien og bare første del er kommet frem.

 

Klienten må selv dele opp strømmen i enkelte meldinger.

Endret av MailMan13
Lenke til kommentar

Problemet er løst, tror jeg..

 

       Dim s As String

       For Each s In message.Split("/"c) 'Message = Tekst sendt fra buffer.


           Dim Messagetosplit As String = "/" & s  'Messagetosplit = Meldingen som skal leses av klienten.


           Dim data() As String = Messagetosplit.Split("|"c) 'Data = deler av meldingen

Next  

 

Tusen takk for all hjelp, du er konge:)

Lenke til kommentar
  • 2 uker senere...

Har sett litt på dette, og derfor lurer jeg på om det går å gjøre så den teksten som sendes fra serveren samles opp av klienten og leveres i sin helhet, ikke for kort eller ikke sammensatt av flere meldinger?

 

Du snakket tidligere om at klienten må selv dele opp strømmen i enkelte meldinger tidligere, det er her det stopper med mine kunskaper..

Lenke til kommentar

public enum MessageType
{
 ConnectionSetup,
 ChatMessage,
 ChatGlobalMessage
}
[serializable()]
public struct ChatPackage
{
 private static readonly System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
 public MessageType Type
 public string[] Recipients;
 public byte[] Data;
 public override string ToString()
 {
   return Encoding.UTF8.GetString(Data);
 }
 public void Send(Stream dst)
 {
   Formatter.Serialize(dst, msg);
 }
 public static ChatPackage FromStream(Stream src)
 {
   return (ChatPackage)Formatter.DeSerialize(src);
 }
}

 

Noe slikt.

Lenke til kommentar
  • 2 måneder senere...

public enum MessageType
{
 ConnectionSetup,
 ChatMessage,
 ChatGlobalMessage
}
[serializable()]
public struct ChatPackage
{
 private static readonly System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
 public MessageType Type
 public string[] Recipients;
 public byte[] Data;
 public override string ToString()
 {
   return Encoding.UTF8.GetString(Data);
 }
 public void Send(Stream dst)
 {
   Formatter.Serialize(dst, msg);
 }
 public static ChatPackage FromStream(Stream src)
 {
   return (ChatPackage)Formatter.DeSerialize(src);
 }
}

 

Noe slikt.

 

 

Fikk ikke noe ut av denne koden, da jeg ikke er en reser i C#...

Men er det noen som har brukt streams og serializers i VB.NET?

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...