 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 15.08.2005, 17:08 Titel: Netzwerk-Chat in freeBasic?? |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 18.08.2005, 17:01 Titel: |
|
|
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 |
|
 |
Progger_X Mr. Lagg
Anmeldungsdatum: 24.11.2004 Beiträge: 784 Wohnort: Leipzig
|
Verfasst am: 24.08.2005, 00:56 Titel: |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 24.08.2005, 14:23 Titel: |
|
|
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 |
|
 |
Progger_X Mr. Lagg
Anmeldungsdatum: 24.11.2004 Beiträge: 784 Wohnort: Leipzig
|
Verfasst am: 25.08.2005, 16:52 Titel: |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 25.08.2005, 20:53 Titel: |
|
|
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 |
|
 |
d.j.peters Gast
|
Verfasst am: 26.08.2005, 02:53 Titel: |
|
|
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
|
Verfasst am: 11.12.2005, 16:07 Titel: Hab da was für dich :-) |
|
|
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 |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 11.12.2005, 17:20 Titel: |
|
|
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 |
|
 |
|
|
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.
|
|