PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ungewollte Ausgabe C++/socket



sauertopf
07-02-2003, 12:53
Hallo neues Forum!

Bei dem Progrämmchen im Anhang wird nach der Ausgabe von bufr auch immer der Inhalt von buf auf dem Bildschirm ausgegeben. Kann mir das bitte einer erklären?

Falls diese Frage irgendwie daneben ist, bitte hinweisen. Bin eben neu.

Gruß, sauertopf



#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>

int create_inet_socket(uint16_t port){

int socket1;
struct sockaddr_in name, namer;

socket1=socket(PF_INET, SOCK_STREAM, getprotobyname("IP")->p_proto);
name.sin_family = AF_INET;
name.sin_port = htons (port);
name.sin_addr.s_addr = htonl (INADDR_ANY);

if (bind(socket1, (struct sockaddr *) &name, sizeof(name)) < 0)
{
perror ("bind");
//exit (EXIT_FAILURE);
}

uint32_t ip=192*2^24+168*2^16+100*2^8+100;
char ipc[3];
ipc[0]=192; ipc[1]=168; ipc[2]=100; ipc[3]=100;
namer.sin_family = AF_INET;
namer.sin_port = htons (80);
struct hostent *hostinfo;
//char gmx[20]="www.gmx.de";
//hostinfo=gethostbyname(gmx);
//cout << ipc << endl;
namer.sin_addr = *(struct in_addr *) ipc;
if (connect(socket1, (struct sockaddr *) &namer, sizeof(namer)) < 0)
{
perror ("connect");
//exit (EXIT_FAILURE);
}
return(socket1);

}

int main(int argc, char *argv[])
{
cout << "Hello, World!" << endl;
int sock=create_inet_socket(57655);
char buf[30]="GET /index.html HTTP/1.0\n\n";
write(sock, &buf, 31);
char bufr[10];
read(sock, &bufr, 11);
cout << bufr << endl;
read(sock, &bufr, 11);
cout << bufr << endl;
close(sock);
return EXIT_SUCCESS;
}


Ausgabe:



Hello, World!
ˬdd\
HTTP/1.0 20@GET /index.html HTTP/1.0


0 OK
Date:@GET /index.html HTTP/1.0

The Ripper
07-02-2003, 14:09
char bufr[10];
read(sock, &bufr, 11);
cout << bufr << endl;

1. Du reservierst Speicherplatz für 10 Bytes, lässt read() aber bis zu 11 Bytes schreiben.
2. cout << string gibt auf dem Bildschirm Zeichen für Zeichen des Strings string aus, bis ein NULL-Zeichen (0x00) gefunden wird.
read() terminiert deinen String aber nicht mit einem NULL, das musst du selbst machen.
bind() wird übrigens für Clients i.A. nicht benötigt.

Anbei ein Musterbeispiel für einen HTTP-Client:

#include<stdio.h>
#include<netdb.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

int main()
{
int sock;
struct hostent *hostinfo;
struct sockaddr_in da;
char *command;
int rsize;
char buffer[100];

/* Name des Zielservers auflösen */
if ((hostinfo = gethostbyname("router")) == NULL)
{
perror("gethostbyname");
return 1;
}

/* Socket erstellen */
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
return 1;
}

/* Mit Zielserver verbinden */
da.sin_family = AF_INET;
da.sin_port = htons(80);
da.sin_addr.s_addr = *((unsigned long*)(*hostinfo).h_addr_list[0]);
// da.sin_addr.s_addr = inet_addr("192.168.0.1");

if (connect(sock, (struct sockaddr*)&da, sizeof(da)) == -1)
{
perror("connect");
return 1;
}

/* Befehl senden */
command = "GET / HTTP/1.0\r\n\r\n";
if (send(sock, command, strlen(command), 0) == -1)
{
perror("send");
return 1;
}

/* Antwort ausgeben */
while((rsize = recv(sock, buffer, sizeof(buffer) - 1, 0)) > 0)
{
buffer[rsize] = 0x00; /* NULL-Zeichen hinter das letzte empfangene Zeichen */
/* hängen */

printf("%i: %s", rsize, buffer);
}

close(sock);

return 0;
}

sauertopf
07-02-2003, 14:34
2. Genau, nullterminiert - jetzt gehts.
1. Also, ich bin mir nicht sicher, aber wenn ich mit char buf[10] reserviere, krieg ich dann nicht 11 Byte, nähmlich von buf[0] bis buf[10]? Is ne echte Frage.
3. Das Beispiel hab ich erst kurz überflogen, mir ist aber gleich der http-code ins Gesicht gesprungen. Ist natürlich besser, dem Server zu überlassen, ob er index.html, index.php, index.htm o. ä. senden will.
4. Der Tip mit dem bind ist auch Gold wert: vermutlich krieg ich jetzt einen Source-Port 80? Muss ich noch prüfen, aber mein sniffer machsts grad nicht.
5. Und dann seh ich mir noch den Unterschied zwischen send/recv und write/read an. Danke!

The Ripper
07-02-2003, 15:22
zu 1. nein, char buf[10] reserviert 10 bytes, von buf[0] bis buf[9]
du kannst möglicherweise trotzdem über das ende des speicherbereiches hinausschreiben, ohne dass dein Programm segfaulted, aber damit überschreibst du Daten in anderen Variablen!
zu 4. Welchen Source-Port dein Socket hat ist egal, wichtig ist, dass du dich mit dem Ziel-Port 80 verbindest.
zu 5. send() und recv() unterstützen noch spezielle Flags, die ich aber im Beispiel nicht (hmm, eigentlich noch überhaupt nicht ;)) verwendet habe. Eigentlich hätten es auch read() und write() getan.