PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : verbindungsorientierter perl 'server'



namous
04-05-2006, 18:53
Ich hab mir (zugegeben mit copy&past) in C einen Client fuer Windows erstellt, der Verbindung zu meinem Perl-Server aufnehmen kann/soll.

Zuerst mal der C-Code des Clients:

#include <windows.h>
#include <winsock2.h>
#include <stdio.h>

int startWinsock(void);

int main()
{
long rc;

SOCKET s;

SOCKADDR_IN addr;

rc=startWinsock();

if(rc!=0)
{
printf("Fehler: startWinsock, fehler code: %d\n",rc);
return 1;
}
else
{
printf("Winsock gestartet!\n");
}

s=socket(AF_INET,SOCK_STREAM,0);

if(s==INVALID_SOCKET)
{
printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError());

return 1;
}
else
{
printf("Socket erstellt!\n");
}

memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten
addr.sin_family=AF_INET;
addr.sin_port=htons(12345); // wir verwenden mal port 12345
addr.sin_addr.s_addr=inet_addr("84.16.229.137"); // zielrechner ist unser eigener

rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));

if(rc==SOCKET_ERROR)
{
printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError());
return 1;
}
else
{
printf("Verbunden.\n");

char buf[256];
strcpy(buf, "Halllooo");
send(s,buf,7,0);
}

return 0;
}

int startWinsock(void)
{
WSADATA wsa;

return WSAStartup(MAKEWORD(2,0),&wsa);
}


Wenn ich das richtig sehe, ist die Verbindung verbindungsorientiert. Ich hab schon erfahrungen mit nicht-verbindungsorientierten Server in Perl, siehe:

use strict;
use IO::Socket;

my $sock = IO::Socket::INET->new( Listen => 5,
LocalAddr => '84.1*.***.***',
LocalPort => 12345,
Proto => 'tcp');

while(my $client = $sock->accept())
{
my $msg = <$client>;
print $msg;
}


Ich hab auch schon diverse Versuche unternommen, einen verbindungsorientierten Server hinzubekommen, hat aber leider nicht geklappt. Hier mal mein letzter Versuch:

use strict;
use IO::Socket;

socket(Server, AF_INET, SOCK_STREAM, getprotobyname('tcp')) || die("socket: $!");
setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die("setsockopt: $
!");
bind(Server, sockaddr_in(12345, INADDR_ANY)) || die("bind: $!");
listen(Server, SOMAXCONN) || die("listen: $!");

for(;;)
{
accept(Client, Server);
my $msg;
recv(Server, $msg, 5, 0);
print $msg;
}


Koenntet ihr mir bitte weiterhelfen, den Perl-Server zu erstellen? Ich waere euch sehr dankbar.

MfG namous

michael.sprick
04-05-2006, 19:06
Erstmal musst Du natürlich sicherstellen, dass Server und client auch den gleichen Port benutzen.

Im Client versuchst Du Dich zu TCP-Port 12345 zu verbinden, im Serverskript öffnest Du aber einen ganz anderen Port...

UND: Der Port, den Du im Server öffnest ist ziemlich weit out-of-range ;) --- also ungültig. Im TCP Stack stehen 16Bit für den TCP Port zur Verfügung - mit anderen Worten, die höchste Portnummer, die Du nutzen kannst, ist 65535.

Außerdem bindest du den Server ja an eine ganz andere IP Adresse, als die, die zu der Du im Client eine Verbindung aufbauen willst... auch bitte bitte erstmal nachbessern.

Zuletzt wären natürlich Fehlermeldungen oder eine Beschreibung Deines Problems ganz hilfreich ...

namous
04-05-2006, 19:13
Joa, ich hab mit den Sourcen gleich weitergetestet und noch andere Sachen versucht, an sich haben die schon immer gestimmt. Ich hab es oben editiert, nu ist es so wie ichs getestet hab und es nicht lief. Naja das mit den Fehlermeldung ist so ein Problem, da kommen ja keine. Aber ich kann euch sagen, was die Programme/Skripte machen, der Client sagt:

Winsock gestartet!
Socket erstellt!
Verbunden.
Aber nur, wenn der Server auch laeuft, also ist wohl so eine Art verbindung schon da. Und der Server sagt einfach garnix und laeuft, bis ihn kill.

MfG namous

namous
09-05-2006, 00:10
Ok, Ok, wollt nicht dumpen, also hab ich weiter getestet und bin weiter gekommen. Mein Problem nun: Ich hab den Perl-Server und den C-Client, der Server schickt an den Client und der kann mir die gesendete Daten ausgeben, aber ich bekomms nicht hin, vom Client an den Server zu schicken, bzw. bekomm ich es nicht hin, dass der Server die Daten ausgibt/empfaengt. Hier der Code, die kommentierten Zeile sind die, bei denen der Server schickt und der Client empfaengt, was funktioniert.

C-Client

#include <stdio.h>
#include <winsock2.h>

#define SERVER_PORT 1234
#define RECV_BUF_MAXLEN 256

long WinsockStartup();

int main()
{
SOCKET sock;
SOCKADDR_IN addr;
long rc;
char recvBuf[RECV_BUF_MAXLEN+1];
char hostAdress[] = "84.16.***.***";

rc = WinsockStartup();

// socket anlegen
sock=socket(AF_INET,SOCK_STREAM,NULL);

/* Informationen fuer Verbindung */
addr.sin_family = AF_INET;
addr.sin_port = htons(SERVER_PORT);
addr.sin_addr.s_addr = inet_addr(hostAdress);

// socket mit Server verbinden, endlos immer wieder probieren
while(
connect(sock, (SOCKADDR*)&addr, sizeof(SOCKADDR))
== SOCKET_ERROR)
{
printf("."); // Lebenszeichen ausgeben
Sleep( 500 ); // 500ms warten
}
// Server gefunden
printf("Verbunden mit %s ...\n", hostAdress);
//Nachricht abholen und ausgeben
//rc = recv(sock, recvBuf, RECV_BUF_MAXLEN, NULL);
//recvBuf[rc] = '\0';
//printf("%d Byte empfangen: %s\n", rc, recvBuf );
strcpy(recvBuf, "jupiii");
send(sock, recvBuf, 5, NULL);

}
/* *************************************************
* Starte Socket Service unter Windows
*/
long WinsockStartup()
{
long rc;

/* gewünschte Version */
WORD wVersionRequested;
/* Datenstruktur fuer Info ueber Version */
WSADATA wsaData;

wVersionRequested = MAKEWORD(2, 1); /* Short Wert aus 2 Bytes */

rc = WSAStartup( wVersionRequested, &wsaData );
return rc;
}

Perl-Server

use strict;
use IO::Socket;

my $sock = IO::Socket::INET->new(Listen => 5, LocalAddr => '84.16.***.***', Loca
lPort => 1234, Proto => 'tcp');

while(my $client = $sock->accept())
{
# send($client, "hallofobar", '');
my $msg;
recv($client, $msg, 4, 0);
print $msg."foo";
}


PS: Will spaeter auch Datein hin und her senden koennen, wie und wo steig ich da am Besten ein?