Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Netzwerk-Chat in freeBasic??

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 15.08.2005, 17:08    Titel: Netzwerk-Chat in freeBasic?? Antworten mit Zitat

Hallo.
Ich hab mal auf freebasic.net vorbeigeguck und das hier gefunden:
http://www.freebasic.net/forum/viewtopic.php?t=298&

Ich kann nicht so gut englisch, aber das sieht ja nach einem tcp/ip Prgramm aus.Ich hab damit versucht ein Chat-Programm zu schreiben, wie Marzec es schon für QBasic geschrieben hat. Ich komme aber nicht weiter, weil kein client irgendeine Nachricht empfängt die der Server schickt. Könnte vielleicht einer von euch mal ein chat-Prog dazu schreiben??(brauch das für ein netzwerk-prog)

Mfg
Michael

EDIT:
Code:

option escape
'$include: "win/winsock.bi"
declare function wsConnect (s as socket, host as string, port as integer)
declare function wsResolveHost   ( hostname as string ) as integer
declare function wsGetData   ( s as socket ) as string
declare function wsSendData   ( s as socket, sendbuffer as string)
declare function wsInit (s as socket)
declare function wsKill (s as socket)
declare function wsListen (s as socket, port as integer)
declare function wsAccept (s as socket)

const RECVBUFFLEN = 8192
const NEWLINE = chr$(13)+chr$(10)'"\r\n"

function wsAccept(s as socket)
   dim acceptsocket as socket
   AcceptSocket = SOCKET_ERROR
   while ( AcceptSocket = SOCKET_ERROR )
      AcceptSocket = accept( s, 0, 0)
   wend
end function
 
function wsListen (s as socket, port as integer)
   dim sa as sockaddr_in
   sa.sin_port      = htons(port)
   sa.sin_family      = AF_INET
   sa.sin_addr.S_addr   = inet_addr( "127.0.0.1" )
   bind( s, @sa, sizeof(sa) )
   listen( s, 1 )
end function

function wsKill(s as socket)
   shutdown(s, 2)
   closesocket(s)
   WSACleanup
end function

function wsInit(s as socket)
   dim wsaData as WSAData
   WSAStartup( MAKEWORD( 1, 1 ), @wsaData )
   s = opensocket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
end function

function wsSendData(s as socket, sendbuffer as string)
   send(s, strptr(sendBuffer), len(sendBuffer),0)
end function

function wsGetData(s as socket) as string
   dim recvbuffer as zstring * RECVBUFFLEN+1
   dim bytes as integer
   bytes = recv(s, strptr(recvBuffer), RECVBUFFLEN, 0)
   recvbuffer[bytes] = 0
   if recvbuffer = "" then
      wsgetdata = trim$(str$(bytes))
   else
      wsgetData = recvbuffer
   end if
   
end function

function wsGetAllData(s as socket) as string
   dim recvbuffer as zstring * RECVBUFFLEN+1
   dim bytes as integer
   while (bytes <> socket_error)
    bytes = recv(s, strptr(recvBuffer), RECVBUFFLEN, 0)
    if ( bytes = 0 or bytes = WSAECONNRESET ) then
       exit while
    end if
wend
recvbuffer[bytes] = 0
 if recvbuffer = "" then
    wsgetalldata = trim$(str$(bytes))
 else
wsgetalldata = recvBuffer
end if
end function

function wsResolveHost( hostname as string ) as integer
   dim ia as in_addr
   dim hostentry as hostent ptr
   ia.S_addr = inet_addr( hostname )
   if ( ia.S_addr = INADDR_NONE ) then
      hostentry = gethostbyname( hostname )
      if (hostentry = 0) then   exit function
      wsresolveHost = **hostentry->h_addr_list
   else
      wsresolveHost = ia.S_addr
   end if   
end function

function wsConnect(s as socket, host as string, port as integer)
   dim connection as sockaddr_in
   connection.sin_port      = htons(port)
   connection.sin_family      = AF_INET
   connection.sin_addr.S_addr   = wsresolveHost(host)
   connect(s, @connection, len(connection))
end function


Code:

'winsockserver.bas
option explicit
option escape

#include "winsockutil.bas"

cls
dim s as socket
print "Initializing..."
wsInit(s)
print "Listening..."
wsListen (s, 9090)
print "Accepting..."
wsAccept (s)
print "Sending..."
wsSendData (s, "moo23wd")
print "Killing..."
wsKill(s)
sleep


Code:

'winsockclient.bas
option explicit
option escape

#include "winsockutil.bas"

cls
dim s as socket
print "Initializing..."
wsInit(s)
print "Connecting..."
wsConnect(s,"127.0.0.1", 9090)
print "Recieving..."
dim moo as string
moo = wsGetallData(s)
print moo
print "Killing..."
wsKill(s)
sleep


Wenn man mit dem code vom Server irgendwas zum client sendet, dann kommt immer die gleiche Zahlenkombination an. Ich vermute, dass das ein Fehlercode ist.

Code:

'winsockserver.bas
option explicit
option escape

#include "winsockutil.bas"

cls
dim s as socket
print "Initializing..."
wsInit(s)
print "Listening..."
wsListen (s, 9090)
print "Accepting..."
wsAccept (s)
print "Sending..."
wsSendData (s, "moo23wd")
sleep 'das hier habe ich jetzt noch dazugeschrieben
print "Killing..."
wsKill(s)
sleep


Mit dem Sleep hinter send data sieht man, dass bei client garnichts ankommt. Erst wenn man im serverfenster eine Taste drückt. Irgendwas scheint also nicht zu klappen. Kennt einer eine Lösung??
_________________
Code:
#include "signatur.bi"
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 18.08.2005, 17:01    Titel: Antworten mit Zitat

Ich hab jetzt mal selbst ein tcp-prog geschrieben(tut von www.c-worker.ch ), und das klappt nicht.(bei send wird immer -1 und bei WSAGetLasteError 10038 zurückgegeben, alles andere klappt einwandfrei) Meine Vermutung: Das liegt an der winsock.dll. Mit Freebasic kann man ja nur version 1.1 nehmen. Wie kann man aus einer .dll eine .dll.a und eine .dll.def machen, damit man sie in freebasic benutzen kann?? Geht das mit dem compiler oder muss man das "manuell" machen?? Die .bi file brauche ich nicht.(functionen die ich brauche kann ich alle im prog declarieren)


Letztes EDIT:
So. Ich habs jetzt geschafft. Ich bin soweit, dass ich vom server zum client senden kann. Umgedreht noch nicht. Wenn ich fertig bin, dann stell ich das ganze mal unter FreeBasic no paste. Habs übrigens mit winsock 1.1 gemacht.
_________________
Code:
#include "signatur.bi"
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Progger_X
Mr. Lagg


Anmeldungsdatum: 24.11.2004
Beiträge: 784
Wohnort: Leipzig

BeitragVerfasst am: 24.08.2005, 00:56    Titel: Antworten mit Zitat

Hi!

Ich kann dir nur empfehlen: steig auf SDL um! Ich hab das mal selber probiert. Ich schreib dir ma noch den Code, dann siehste, wies funktioniert:
(ich übertrage allerdings die Gedrückten Tasten, nicht Nachrichten und das löschen von Buchstaben funzt net, das hab ich vor nem Monat oder so mal gemacht aus langeweile)

Code:
'$include: "SDL/SDL_net.bi"
'$include: "SDL/SDL.bi"
DECLARE SUB Connect(Socket as tcpsocket,nummer)
DIM taste(100) AS string
DIM nachricht(100) AS string
DIM sockclient(100) AS tcpsocket
IF SDLNet_Init() <> 0 THEN
    PRINT "Fehler"
    SLEEP
    END
END IF
PRINT "1-Server"
PRINT "2-Client"
DO
    dummy$=INKEY$
    nummer=VAL(dummy$)
LOOP UNTIL nummer=1 OR nummer=2
DIM sock AS tcpsocket'Socket einstellen
DIM ip AS ipaddress'Variable IP vom Typ IP Addresse
IF nummer=1 THEN
   SDLNet_Write32( INADDR_ANY, @ip.host )
   SDLNet_Write16( 5678, @ip.port )
   sock = SDLNet_TCP_Open( @ip )'TCP Verbindung öffnen, in den Socket schreiben
   zahler=1
   PRINT "Warte auf Client..."
   WHILE sockclient(1) = NULL
      sockclient(1) = SDLNet_TCP_Accept( sock )
   WEND
END IF
IF nummer=2 THEN
   INPUT "IP Addresse des Hostes: ", host$
   SDLNet_ResolveHost( @ip, host$, 5678 )
   sockclient(1) = SDLNet_TCP_Open( @ip )
END IF
ypos=3
CLS
IF nummer=1 THEN anderer=2 ELSE anderer=1
#define delay 0.03
t#=TIMER+delay
DO
   WHILE TIMER<T#:WEND
   t#=TIMER+delay
   taste(nummer)=INKEY$
   hilfsvar=ASC(taste(nummer))
   IF taste(nummer)="" THEN hilfsvar=0
   SDLNet_TCP_Send(sockclient(1), @hilfsvar, 2 )
   SDLNet_TCP_Recv(sockclient(1), @hilfsvar, 2 )
   FOR zahl=2 TO 10
      IF sockclient(zahl)=NULL THEN
         sockclient(zahl) = SDLNet_TCP_Accept( sock )
      ELSE
         SDLNet_TCP_Send(sockclient(zahl), @hilfsvar, 2 )
         SDLNet_TCP_Recv(sockclient(zahl), @hilfsvar, 2 )         
      END IF
   NEXT
   taste(anderer)=CHR$(hilfsvar)
   IF hilfsvar=0 THEN taste(anderer)=""
   SCREENLOCK
   LOCATE 1,1
   PRINT nachricht(nummer)
   FOR zahl=1 TO 10
      IF taste(zahl)<>CHR$(27) AND taste(zahl)<>CHR$(13) AND taste(zahl)<>"" THEN
         nachricht(zahl)=nachricht(zahl)+taste(zahl)
      END IF
      IF taste(zahl)=CHR$(13) THEN ypos=ypos+1
      IF taste(zahl)=CHR$(13) THEN
         IF nummer=zahl THEN
            LOCATE 1,1
            PRINT "                                            "
         END IF
         LOCATE ypos,1
         IF nummer=1 THEN
            PRINT "Sie: "+nachricht(zahl)
         ELSE
            PRINT "Ihr Freund: "+nachricht(zahl)
         END IF
         nachricht(zahl)=""
      END IF
      IF taste(zahl)=CHR$(27) THEN
         PRINT "Ein User ist gegangen"
      END IF
   NEXT
   SCREENUNLOCK
LOOP UNTIL e=1


SUB Connect(socket as tcpsocket,nummer)
IF SDLNet_Init() <> 0 THEN
    PRINT "Fehler"
    SLEEP
    END
END IF
PRINT "1-Server"
PRINT "2-Client"
DO
    dummy$=INKEY$
    nummer=VAL(dummy$)
LOOP UNTIL nummer=1 OR nummer=2
DIM sock AS tcpsocket'Socket einstellen
DIM sockclient AS tcpsocket
DIM ip AS ipaddress'Variable IP vom Typ IP Addresse
IF nummer=1 THEN
   SDLNet_Write32( INADDR_ANY, @ip.host )
   SDLNet_Write16( 5678, @ip.port )
   sock = SDLNet_TCP_Open( @ip )'TCP Verbindung öffnen, in den Socket schreiben
   zahler=1
   PRINT "Warte auf Client..."
   WHILE socket = NULL
      socket = SDLNet_TCP_Accept( sock )
   WEND
END IF
IF nummer=2 THEN
   INPUT "IP Addresse des Hostes: ", host$
   SDLNet_ResolveHost( @ip, host$, 5678 )
   socket = SDLNet_TCP_Open( @ip )
END IF
END SUB
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 24.08.2005, 14:23    Titel: Antworten mit Zitat

Ich habe das aber alles viel einfacher. Zum connecten muss man nur con aufrufen, zum daten senden senddata und zum empfangen getdata. Die subs stehen in ner anderen datei. Im client brauch ich nur 50 Zeilen, im Server 68. Und alles geht sehr einfach mit mehreren clients. Ich werde den code mal in fbnp posten.

Mfg
Michael
[/code]
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Progger_X
Mr. Lagg


Anmeldungsdatum: 24.11.2004
Beiträge: 784
Wohnort: Leipzig

BeitragVerfasst am: 25.08.2005, 16:52    Titel: Antworten mit Zitat

Ok, da bin ich mal gespannt.

Aber viel mehr Zeilen hat der Code auch net, und der ist für client und Server.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 25.08.2005, 20:53    Titel: Antworten mit Zitat

Im Moment hab ich nur noch ein Problem, dass getdata ein blocking call ist. Im Server hab ich das mit fd_set gelöst. Das ist glaube ich eingetragen, ob eine Nachricht von einem client vorliegt. Im client selber klappt das nicht. Also muss ich zur Zeit im Server die ganze zeit daten zum client senden, damit der nicht anhält. Ich hab schonmal an Threadcreate gedacht, aber das gefällt mir nicht. ICh finde aber nichts, wie man das anders machen kann.

Mfg
MIchael
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
d.j.peters
Gast





BeitragVerfasst am: 26.08.2005, 02:53    Titel: Antworten mit Zitat

http://zotteljedi.de
Die Seite mit den besten deutschen Tutorials über Sockets und Netzprogrammierung die ich kenne WIN, LIN.

Grüsse Joshy
Nach oben
max06



Anmeldungsdatum: 05.12.2004
Beiträge: 390
Wohnort: Augsburg

BeitragVerfasst am: 11.12.2005, 16:07    Titel: Hab da was für dich :-) Antworten mit Zitat

Moin,

ich hab selber erst vor kurzem einen Chat geschrieben, welcher aber alle Nachrichten über ne MySQL-Datenbank austauscht. Bei Interesse lasse ich dir gerne mal den Code zukommen...


Greets
Florian
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Michael712
aka anfänger, programmierer


Anmeldungsdatum: 26.03.2005
Beiträge: 1593

BeitragVerfasst am: 11.12.2005, 17:20    Titel: Antworten mit Zitat

Hallo.

Ich habe ja mittlerweile schon alles selbst geschafft, deinen chat habe ich übrigens schon getestet. Das kleine Problem bei mir ist das empfangen von daten bei den clients. Dafür habe ich zur Zeit noch einen thread. Sont läuft bei mir aber alles einwandfrei. Trotzdem Danke.

Michael

EDIT: Jetzt wird alles mit select geprüft, also brauch ich nur noch 1 thread.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz