Gå til innhold

Ikke bare klient-til-server chat


Anbefalte innlegg

Hallo

 

Nå har jeg jobba lenge med en chat som viste seg å bare kunne ta to stykker!! Skikkelig ergelig fordi jeg har brukt lang tid og lagd ekstra funksjoner selv.. Noen som vet hvordan jeg kan gjøre det om til en "fler-bruker" chat? jeg bruker sånn:

 

server

    tcpServer.LocalPort = Text1.Text 
   tcpServer.Listen

##########

   Dim strdata As String
   tcpServer.GetData strdata

   lstMsg.AddItem strdata

 

Klient

Dim ipStr, portStr As String
ipStr = InputBox("Skriv serverens ip-adresse", "IP-Adresse")
portStr = InputBox("Skriv hvilken port", "Port")

tcpClient.Connect ipStr, portStr

###########

   Dim strdata As String
   tcpClient.GetData strdata
   lstMsg.AddItem strdata

 

Blir det veldig mye styr med det eller går det greit?

Endret av Jonas
Lenke til kommentar
Videoannonse
Annonse

Det går vel greit, men for å forklare hvordan man lager et flerbruker chatteprogram viser jeg deg likegjerne et:

 

http://home.online.no/~aadnk/Filer/Chatprogram.zip

 

Dette er et chatteprogram der alt styres ved kommandoer. Det var bare ment som et eksempel, så derfor gadd jeg ikke å lage en GUI :D.

 

Du lager en server med: /bind

Og kobler til en server med: /connect [iP]

 

For å teste det kan du jo ganske enkelt åpne flere programmer og så først gjøre den ene til en server, og la de andre koble seg opp mot dem med /connect localhost.

 

Den har mangen muligheter, bland annet et script språk som kan gjøre utrolig mye (faktisk alt, så det er derfor dette egentlig ikke skulle brukes til mer enn et eksempel)

Lenke til kommentar
jeg regner med at med "chatten tar bare 2 stk" så mener du at du kun kan ha 1 client tilkoblet servere?

 

Isåfall så er det pga at socketen som lytter blir opptatt da den får en client, og dermed lukket. Du må lage en løsning som kan akseptere tilkobligen på en annen socket enn den som lytter.

Altså jeg må lage fler winsocker? og alt som kommer inn på (server) recived data (elns) sendes ut til alle winsocker som er i bruk? er det bare det? hmm, da gjør jeg det når jeg kommer hjem :roll:

 

Edit:

aadnk, ser på programmet nå, men jeg blir bare forvirret av det! masse koder der jeg ikke skjønner bæret av.. Går det ikke ann å endre noe på den jeg har istedenfor å skrive hele greia på nytt? :(

 

Hvis det hjelper noe så ligger hele prosjektet her..

Endret av jonas22282460
Lenke til kommentar
Isåfall så er det pga at socketen som lytter blir opptatt da den får en client, og dermed lukket. Du må lage en løsning som kan akseptere tilkobligen på en annen socket enn den som lytter.

Ehhh.

 

Det er nå vel slik at porten på klienten blir opptatt av et utgående program.

 

La oss ta en eksempel:

Web-klient til Web-server

Web-server lytter til port 80, og håndterer flere forespørsler samtidig på denne porten.

Web-klienter binder mot en port, og dermed vil ingen andre klient-programmer eller servere få tilgang til denne utgående porten.

Lenke til kommentar
For å få scrollen til å være nede hele tiden kan du legge til dette etter vær gang prosedyren AddItem brukes:

 

lstMsg.ListIndex = lstMsg.ListCount - 1

 

Les litt på http://www.winsockvb.com for å forstå hvordan du skal ha flere enn to brukere, siden de har noen veldig gode artikler om dette.

Jeg leste Receive multiple connections og Winsock control arrays, men skjønte egentlig ikke noe av hva de snakka om.. Finnes det ikke en norsk artikkel om dette noe sted?

Lenke til kommentar
Isåfall så er det pga at socketen som lytter blir opptatt da den får en client, og dermed lukket. Du må lage en løsning som kan akseptere tilkobligen på en annen socket enn den som lytter.

Ehhh.

 

Det er nå vel slik at porten på klienten blir opptatt av et utgående program.

 

La oss ta en eksempel:

Web-klient til Web-server

Web-server lytter til port 80, og håndterer flere forespørsler samtidig på denne porten.

Web-klienter binder mot en port, og dermed vil ingen andre klient-programmer eller servere få tilgang til denne utgående porten.

Det var jo nøyaktig det samme som han sa jo...

 

Poenget er at da servern får en tilkobling så accepter du på en annen socket. En løsning er å lage en array av sockets som kan utvides etterhvert som du får tilkoblinger.

Lenke til kommentar

er lenge siden jeg har kodet i VB, men kan alltids prøve å forklare. Jeg tar utgangspunkt i at du ikke vet hva en array er.

 

En array er en samling av variabler lagret under et felles navn, men med forskjellige indeksverdier. I VB kan du lage arrays (dim) med X antall objekter (går også med flere dimensjoner. x, y, z, osv...). Det er også mulig å gjøre om størrelsen senere (redim elno) ved behov. Ved hjelp av dette kan du lage en løsning hvor du kan opprette variabler etter behov mens programmet kjører. Løsningen her kan være at du lager en array av sockets. Da listen socketen din mottar en request hvor den må kjøre socket.accept så oppretter du en ny socket, accepter, og legger den i arrayen. Så gjenåpner du den originale socketen.

 

Det jeg har skrevet her er veldig generelt, men håper det hjelper litt.

Lenke til kommentar
er lenge siden jeg har kodet i VB, men kan alltids prøve å forklare. Jeg tar utgangspunkt i at du ikke vet hva en array er.

 

En array er en samling av variabler lagret under et felles navn, men med forskjellige indeksverdier. I VB kan du lage arrays (dim) med X antall objekter (går også med flere dimensjoner. x, y, z, osv...). Det er også mulig å gjøre om størrelsen senere (redim elno) ved behov. Ved hjelp av dette kan du lage en løsning hvor du kan opprette variabler etter behov mens programmet kjører. Løsningen her kan være at du lager en array av sockets. Da listen socketen din mottar en request hvor den må kjøre socket.accept så oppretter du en ny socket, accepter, og legger den i arrayen. Så gjenåpner du den originale socketen.

 

Det jeg har skrevet her er veldig generelt, men håper det hjelper litt.

Nå begyner jeg å forstå litt her :roll: du har ikke noe kode eller en norsk artikkel?

Lenke til kommentar

Det du gjør er å først legge inn en Control Array i Server formen. Det gjør du ved å legge til en Winsock og så endre Index propetien til 0.

Du skulle nå ha en Control array med navn Winsock1

 

Det vi skal gjøre er å bruke connection request som Winsock1(0) får (siden bare en winsock kan ha den samme porten) og så akseptere den i en annen control i arrayen. Vi lager dynamisk nye controler for å slippe å sløse med system ressurser.

 

Legg noe lignende dette i formen:

 

Private Sub Form_Load()

' Sett winsock til å vente på tilkoblinger fra klientene på port 80
Winsock1(0).LocalPort = 80 ' setter porten til 80
Winsock1(0).Listen ' venter på tilkoblings forespørsler

End Sub

Private Sub Winsock1_ConnectionRequest(Index As Integer, ByVal requestID As Long)

Dim Buff&
' En klient har spurt om å koble seg til, allocer en control og aksepter tilkoblingen
' For å spare på ressurser sjekker vi om noen controler er ledige:

Buff = GetFreeControl

If Buff < 0 Then
Buff = Winsock1.Count
Load Winsock1(Buff)
End If

Winsock1(Buff).Accept requestID

End Sub

Private Sub Winsock1_DataArrival(Index As Integer, ByVal bytesTotal As Long)

Dim Buff$

' Legg inneholdet som klienten sente i BUFF
Winsock1(Index).GetData Buff

' Printer dataen i debug vinduet (trengs ikke, bare for å teste)
Debug.Print Buff

End Sub

Public Function GetFreeControl() As Integer

Dim Tell%

' Søk gjennom alle kontroller i arrayen
For Tell = 1 To Winsock1.Count - 1
If Winsock1(Tell).State <> sckConnected And Winsock1(Tell).State <> sckConnecting Then GetFreeControl = Tell: Exit Function
Next

' Ingen er ledige, returner -1
GetFreeControl = -1

End Function

 

Klienten kobler bare til serveren og vil automatisk få en egen socket.

Koden er som den alltid har vært:

 

Winsock1.Connect "217.77.34.213", 80

 

Edit: Endret kode på linje 46 (i GetFreeControl, For Tell = .... )

Endret av aadnk
Lenke til kommentar

Tuuusen takk!! men ejg har et lite problem (som vanlig :blush: ) Jeg har en close server knapp og den bruker tcpServer.close kommandoen, men når jeg skal kompilere den så får jeg bare error! Method or data not found.. Får den fordi det ikke er noe som heter tcpServer men mange forskjellige sånne eller såkalte "arrays" ?

Endret av jonas22282460
Lenke til kommentar

Ja, du kan ikke skrive Winsock.Close når hvis den er en Control Array.

Skal du close serveren ville jeg ha gjort noe sånt:

 

Dim Tell%

tcpServer(0).Close ' Winsocken som motar tilkoblings requests

' Fjerner alle tcpServer controller untatt 0
For Tell = 1 To tcpServer.Count - 1
tcpServer(Tell).Close
Unload tcpServer(Tell)
Next

Lenke til kommentar

Må klientene det også eller bare serverne? Alt som kommer inn, blir det automatisk sendt ut til alle eller må jeg legge til sånn at inndata blir sendt ut med den koden du ga meg?

 

Edit: tuuusen takk, men som vanlig har jeg et problem :blush: hver gang noen connecter til serveren får jeg en error:

 

Private Sub tcpServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
   'check for tcpserver state if it is NOT CLOSED then accept request

Dim Buff&
' En klient har spurt om å koble seg til, allocer en control og aksepter tilkoblingen
' For å spare på ressurser sjekker vi om noen controler er ledige:

Buff = GetFreeControl

If Buff < 0 Then
Buff = tcpServer.Count
Load tcpServer(Buff)
End If

[B]tcpServer(Buff).Accept requestID[/B]

 

tcpServer(Buff).Accept requestID blir gult og får en feilmelding: run time error '40020': invalid operation at curent state

 

Vet du hvorfor?

 

Edit: missa litt mye i quoteinga her

Endret av jonas22282460
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...