WinFuture-Forum.de: Programm Um Befehle An Server Zu Schicken - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

Programm Um Befehle An Server Zu Schicken funktioniert jetzt


#1 Mitglied ist offline   2cool 

geschrieben 12. August 2006 - 13:29

Hi,


ich schreibe gerade an einem kleinen Programm in C, das eine einfache TCP-Verbindung zu einem beliebigen Host an einem beliebigen Port aufbauen kann. In der Theorie recht simpel, in der Praxis auch, wären da nicht.....


.....ja, wären da nicht einige, ich nenne es mal Defizite in meiner C-Praxis, die ich gerade auszubessern Versuche. Daher bin ich auch bei folgenden Problem im ersten Moment etwas ratlos. Dieses Mini-Programm (nur zum Testen der sprintf-Funktion) funktioniert ohne Fehler. Man beachte die Zeile mit der sprintf-Funktion:

#include <stdio.h>

int main(void) {
  char  send_buf[256];
  char* command;
  printf("command: ");
  scanf("%s", command);
  sprintf(send_buf, "%s\n\n", command);
  puts(send_buf);
  return 0;
}



Das folgende Listing ist das Programm, das die TCP-Verbindung aufbauen kann. Leider macht verursacht diese Funktion einen fehlerhaften Speicherzugriff und das Programm wird von XP beendet. In den Zeilen mit den Comments vermute ich das Problem, da das Programm bis dahin alle Ausgaben liefert:


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

void perr_exit(char* msg, int ret_code)
{
  printf("%s, Error: ",msg);
  printf("%d\n",ret_code);
  exit(ret_code);
}

void usage(char* progname)
{
  printf("\nUsage:\t");
  printf("%s <Host> <Port>\n",progname);
  printf("\tHost:  Host to connect\n");
  printf("\tPort: Port to connect\n");
  exit(0);
}

int main(int argc, char** argv)
{
  char* host;
  char* command;
  char  buf[1024];
  char  send_buf[256];
  char  recv_buf[256];
  long  rc;
  long port;
  SOCKET s;
  SOCKADDR_IN addr;
  WSADATA wsa;
  HOSTENT* hent;
  
  if(argc == 3) {
	host=argv[1];
	port=atol(argv[2]);
  } else {
	usage(argv[0]);
  }

  if(WSAStartup(MAKEWORD(2,0),&wsa))
	perr_exit("WSAStartup failed",WSAGetLastError());

  addr.sin_family=AF_INET;
  addr.sin_port=htons(port);

  printf("Host: %s\n",host);
  printf("Port: %d\n",port);
  printf("Connecting....\n");

  if((addr.sin_addr.s_addr=inet_addr(host))==INADDR_NONE)
  {
	if(!(hent=gethostbyname(host)))
	  perr_exit("Cannot resolve Host",WSAGetLastError());

	strncpy((char*)&addr.sin_addr.s_addr,hent->h_addr,4);

	if(addr.sin_addr.s_addr==INADDR_NONE)
	  perr_exit("Cannot resolve Host",WSAGetLastError());
  }

  if((s=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
	perr_exit("Cannot create Socket",WSAGetLastError());

  if( connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)))
	perr_exit("Cannot connect",WSAGetLastError());

  printf("Connected to %s\n",host);
  
  printf("Send command: ");
  
  scanf("%s", command);
  
  //scanf("%s", send_buf);
  
  sprintf(send_buf, "%s\n\n", command); // *** error ***
  
  printf("debug send_buf: \"%s\n\"", send_buf); // *** not shown ***

  if((send(s,send_buf,strlen(send_buf),0))<strlen(send_buf))
	perr_exit("Cannot send Data",WSAGetLastError());

  printf("Command was send...\n");

  while((rc=recv(s,recv_buf,255,0))>0)
  {
	recv_buf[rc]='\0';
	printf("%s",recv_buf);
  }
  
  closesocket(s);
  return 0;
}


Ändert man die Stelle im Code in der Form um, wie ich es auch in den Comments angedeutet habe, also indem man auf die sprintf-Funktion verzichtet und die Befehlszeile direkt in send_buf einliest, gibt es keine Probleme. Ich möchte die sprintf-Funktion, die im ersten Beispiel ja auch funktioniert, aber gerne in meinem Programm einsetzen.

Das ganze ist mit Absicht bisher mit Absicht sehr einfach gehalten, dennoch bin ich verwundert, dass die gleiche Funktion einmal funktioniert (Testprogramm, erstes Listing) und im einmal nicht. :wink:

Woran kann das liegen?

MfG aus HH



ps: Das Listing basiert auf diesem Winsock-Tutorial: http://www.c-worker....nsock/getpage.c

ps2: ich hab's. Dämliche Pointer, char* command, ich glaub' c will immer eine Grössenangabe haben, mit char command[256] funktioniert es. :wink:

Dieser Beitrag wurde von 2cool bearbeitet: 13. August 2006 - 13:04

greetz, 2cool

web: cmd-script
mail: [email protected]
0

Anzeige



#2 Mitglied ist offline   2cool 

geschrieben 12. August 2006 - 18:20

Hab' den Thread eben umbenannt, ist echt praktisch, wenn man als User das kann. :imao:



Das Problem hat sich nämlich jetzt verlagert, bzw. es gibt ein Neues:

Wie kann man feststellen, ob das Socket gerade Daten bereit hält, ohne den Thread zu blockieren?
Beispielsweise eine Funktion, die die Anzahl an verfügbaren Zeichen zurückgibt oder so.....

Gibt es das, wenn ja (muss es doch eigentlich geben) wie heisst die Funktion?



MfG aus HH

Dieser Beitrag wurde von 2cool bearbeitet: 12. August 2006 - 18:22

greetz, 2cool

web: cmd-script
mail: [email protected]
0

#3 Mitglied ist offline   2cool 

geschrieben 13. August 2006 - 13:01

Hi,


ich habe es hinbekommen. Mit dem kleinen Programm kann man jetzt ganz nette Sachen anstellen. Theoretisch sollten diese Dinge auch mit dem MS-Telnet Client möglich sein, aber der zerstückelt die Ausgabe immer sehr unschön und hat imho auch noch ein paar andere Macken. Im Prinzip bietet das Programm einen Teil der Funktionen von NetCat, der Source sollte aber wesentlich leichter zu verstehen sein.



Hier ein paar Beispiele, was man so alles mit dem Proggi machen kann:

Zitat

C:\>netline

Usage: C:\netline.exe <Host> <Port>
Host: Remote-Host to connect
Port: Remote-Port to connect

C:\>




Mail verschicken:
-----------------

C:\>netline mailto.t-online.de 25
Host: mailto.t-online.de
Port: 25
Connecting.....
Connected to mailto.t-online.de
Command to send: helo
Send done, receiving.....
220 XXXXX.sul.t-online.de T-Online ESMTP receiver XXXXXXXX ready. / T-Online ES
MTP Empfaenger mailto.t-online.de bereit.
250 Ok. / In Ordnung.
Command to send: mail from: <[email protected]>
Send done, receiving.....
250 2.1.0 Sender accepted. / Absender akzeptiert.
Command to send: rcpt to: <[email protected]>
Send done, receiving.....
250 2.1.5 Recipient accepted. / Empfaenger akzeptiert.
Command to send: data
Send done, receiving.....
354 Ok, start with data. / Bereit zum Datenempfang.
Command to send: blabla
Send done, receiving.....
Command to send: bla
Send done, receiving.....
Command to send: bla
Send done, receiving.....
Command to send: blabla
Send done, receiving.....
Command to send:
Send done, receiving.....
Command to send: .
Send done, receiving.....
250 2.0.0 Message accepted. / Nachricht akzeptiert.
Command to send:
Send done, receiving.....
Command to send: quit
Send done, receiving.....
221 2.0.0 XXXXX.sul.t-online.de closing. / Verbindung wird getrennt.
Connection was closed by server

C:\>





Whois-Server abfragen:
----------------------
(ganz Wien,...)


C:\>netline whois.nic.at 43
Host: whois.nic.at
Port: 43
Connecting.....
Connected to whois.nic.at
Command to send: falco.at
Send done, receiving.....
% Copyright ©2005 by NIC.AT (1)
%
% Restricted rights.
%
% Except for agreed Internet operational purposes, no part of this
% information may be reproduced, stored in a retrieval system, or
% transmitted, in any form or by any means, electronic, mechanical,
% recording, or otherwise, without prior permission of the NIC.AT
% on behalf of itself and/or the copyright holders. Any use of this
% material to target advertising or similar activities are explicitly
% forbidden and can be prosecuted.

domain: falco.at
registrant: VNJH2177404-NICAT
admin-c: VNJH2177404-NICAT
tech-c: MTMG2177405-NICAT
zone-c: MTMG2177405-NICAT
nserver: dns1.wpc-systems.de
remarks: 85.190.5.20
nserver: dns2.wpc-systems.de
remarks: 212.227.107.11
changed: 20060220 13:48:58
source: AT-DOM

personname: Maria Hoelzel
organization: Verlassenschaft nach Johann Hoelzel
street address: Schottenfeldgasse 7/3/10
postal code: A-1070
city: Wien
country: Austria
nic-hdl: VNJH2177404-NICAT
changed: 20060220 13:48:57
source: AT-DOM

personname: Thomas Mikscha
organization: Marketingservice Thomas Mikscha GmbH
street address: Josefstr. 37
postal code: 3100
city: St. Poelten
country: Austria
nic-hdl: MTMG2177405-NICAT
changed: 20060220 13:48:57
source: AT-DOM

Connection was closed by server

C:\>





Webseite abrufen:
-----------------

C:\>netline www.banana.com 80
Host: www.banana.com
Port: 80
Connecting.....
Connected to www.banana.com
Command to send: GET /
Send done, receiving.....
<html>
<head><title>Traveler.com</title></head>
<body>
<div style="vertical-align: middle; text-align: center; padding-top: 10%;">
<h2>Another fantastic site brought to you by</h2>
<a href="http://www.traveler.com"><img src="http://traveler.com/images/travelerl
ogoC.jpg" border="0" alt="">
</a>
</div>
</body></html>
Connection was closed by server

C:\>





Ftp-Server testen:
------------------

C:\>netline ftp.mozilla.org 21
Host: ftp.mozilla.org
Port: 21
Connecting.....
Connected to ftp.mozilla.org
Command to send: quit
Send done, receiving.....
220 (vsFTPd 2.0.1)
221 Goodbye.
Connection was closed

C:\>



Eigentlich ist das ganze mehr gedacht, um mir die Funktion der Winsock verständlich zu machen, vielleicht interssiert es aber den einen oder anderen. Ich hab' den fertigen Source mit den Beispielen und einer fertig kompilierten Version in ein Zip gepackt:

Angehängte Datei(en)


Dieser Beitrag wurde von 2cool bearbeitet: 13. August 2006 - 13:07

greetz, 2cool

web: cmd-script
mail: [email protected]
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0