paradiseooo
Goto Top

C - Netzwerkprogrammierung - Windows-Client zu Ubuntu-Server (in VM)

Hallo,

ich bin relativ neu in dem Thema und bräuchte hier einmal dringend Hilfe!
Mein Vorhaben ist es zwischen meinem Windows-Client und meiner VM über das Netzwerk zu kommunizieren.
Leider weiß ich nicht wo mein Fehler sein könnte.
Host-IP: 192.168.1.192; IP-Ubuntu: 192.168.1.64

Mein Script auf der VM (Ubuntu) scheint zu laufen und der Server scheint auf die jeweilige Verbindung zu horchen...
Hier wartet dieser auf seinen Connect mit dem Client.
Das Client-Script (Windows) bricht mir allerdings immer weg und kann keine Verbindung mit dem Server herstellen.
Hier habe ich die Vermutung, das mein connect() nicht sauber läuft, finde aber leider seit mehreren Tagen, keinen Ansatz dieses in den Griff zu bekommen.

Funktioniert das in der Art?
Sieht jemand schon vor dem dem jeweiligen listen() am Server oder dem connect() beim Client einen Fehler?
Muss ich vor dem Starten der Scripte etwas beachten? Eventuell Portfreigaben?

Bin hier leider im Moment etwas auf dem Holzweg :/

/* Server - Ubuntu
*******************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
////////////////////////////////////
#ifdef _WIN32
int betriebssystem = 1;
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <ws2def.h>
#pragma comment(lib, "Ws2_32.lib") 
#include <windows.h>
#include <io.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int betriebssystem = 2;
#endif
///////////////////////////////////
///////////////////////////////////
///////////////////////////////////
///////////////////////////////////
//#define HTTP_PORT 20480
#define MAXBUF 8192

int sock;
int port;
int protokoll;
int partner_address_len;
int partner_verbindung;
struct sockaddr_in host_addr, partner_sock_addr;
struct hostent *hostinfo;
//char *host, *file;
//char command[1024];
//char buf[1024];
//unsigned int bytes_sent, bytes_recv;
//////////////////////////////////
int int_besteatigen;
int binden;
int listen_puffer;
int beenden = 0;
char buffer[MAXBUF];
int msg_len;
//////////////////////////////////

int main(int argc, char **argv) {


    //Socket esretllen
    printf("Initialisierung des Sockets");  
    sock = socket(AF_INET, SOCK_STREAM, 0);

    //Adresse des Servers festlegen
    memset( &host_addr, 0, sizeof (host_addr));
    host_addr.sin_family = AF_INET;
    protokoll = host_addr.sin_family;

    //Port festlegen
    host_addr.sin_port = htons(20480);
    port = host_addr.sin_port;

    //IP-Adresse festlegen
    host_addr.sin_addr.s_addr = inet_addr("192.168.1.64");  

    //Anbindung der Port ID an das Socket() - mit BIND()
    binden = bind(sock, (struct sockaddr*)&host_addr, sizeof(host_addr));

    //Warteschlange
    listen_puffer = listen(sock, 5);

    /*Hier hängt sich das Script auf, da selbstverständlich keine Verbindung zu stande kommt*/
    
    while(beenden != 1){

        if(beenden == 1){

            exit(0);

        }

        /* Initialisiere TCP für Windows ("winsock") */ 
        if (betriebssystem == 1){

            return 0;
  
        }

        /* Initialisiere TCP für Linux */
        else{

            printf("\n*******************************************************");  
            printf("\nElse Zweig - Linux");  
            printf("\n*******************************************************");  
            //Internet Protokoll Vers.2 == IPv4
            printf("\nInternet Protokoll Server:            %d", protokoll);  
            printf("\nIP-Adresse Server:                    %s", inet_ntoa(host_addr.sin_addr));  
            printf("\nPort Server:                          %d", port);  
            printf("\nSocket:                               %d", sock);  
            //binden muss 0 sein bei Erfolg
            printf("\nVariable Gebundener Port -> Socket :  %d", binden);  
            printf("\n*******************************************************\n");  

            //Annahme von Client Verbindungen - Neuer Socket zum aufrufenden Client anlegen
            printf("\n\nVerbindung...");  
            partner_address_len = sizeof(partner_sock_addr);
            partner_verbindung = accept(sock, (struct sockaddr *)&partner_sock_addr, (socklen_t *)&partner_address_len);
            printf("\nVerbindung: %d", partner_verbindung);  
            sleep(5);

            }

/*
            //Warten auf Anfrage des Client
            //recv() zum Einlesen von Daten
            //recv() Buffer zwischen Host und Client muss zur Erreichung gleich definiert sein
            msg_len = recv(partner_verbindung, buffer, MAXBUF , 0);
            printf("\nAnfrage des: %s\n", buffer); 

            
            //Error Logs2
            if(msg_len == -1){

                perror("\nrecv()"); 
                exit(EXIT_FAILURE);

            }
    

            //Senden des Buffer Speichers zurück an den Client
            sprintf(buffer, "\nSenden an Clienten: %s", "Server_kuhkuh"); 
            send(partner_verbindung, buffer, strlen(buffer), 0);
*/
            //Beenden Verbindung zum Clienten
            close(partner_verbindung);

        }

        //Server Script beenden
        if(beenden == 0){


            printf("\n\nZum beenden bestätigen Sie mit 8:: ");  
            scanf("%d", &int_besteatigen);  

            if(int_besteatigen == 8){

                beenden = 1;
                exit(0);

            }
        }

        else{

            return 0;
        }

    }
}


und der Client...

/* Client-Windows Script
************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
////////////////////////////////////
#ifdef _WIN32
int betriebssystem = 1;
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <ws2def.h>
#pragma comment(lib, "Ws2_32.lib") 
#include <windows.h>
#include <io.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int betriebssystem = 2;
#endif
///////////////////////////////////
///////////////////////////////////
///////////////////////////////////
///////////////////////////////////
#define MAXBUF 8192

int sock;
int port;
int protokoll;
int ip_address_fehler;
int partner_address_len;
int partner_verbindung;
struct sockaddr_in host_addr, partner_host_addr;
struct hostent *host;
//////////////////////////////////
int int_besteatigen;
int binden;
int beenden = 0;
long rc;
char buffer[MAXBUF];
int msg_len;
//////////////////////////////////

int startWinsock(void){

    WSADATA wsaData;
    //return WSAStartup(MAKEWORD(2,0),&wsa);
    int wVersionRequested;
    wVersionRequested = MAKEWORD (1, 1);

    if (WSAStartup (wVersionRequested, &wsaData) != 0){

        fprintf( stderr, "Failed to init windows sockets\n");  
        exit(1);

    }

    return WSAStartup;

}

int main(int argc, char **argv) {

    while(beenden != 1){

        if (betriebssystem == 1){

            printf("\nInitialisierung des Windows Sockets");  

            rc = startWinsock();

            sock = socket(AF_INET, SOCK_STREAM, 0);

            //Adresse des Servers festlegen
            memset( &partner_host_addr, 0, sizeof(partner_host_addr));
            partner_host_addr.sin_family = AF_INET;
            protokoll = partner_host_addr.sin_family;

            //Port festlegen
            partner_host_addr.sin_port = htons(20480);
            //partner_host_addr.sin_port = getservbyname("http","tcp"); 
            port = partner_host_addr.sin_port;

            //IP-Adresse des Servers festlegen
            partner_host_addr.sin_addr.s_addr = inet_pton(AF_INET, "192.168.1.64", &partner_host_addr.sin_addr.s_addr);  

            printf("\n*******************************************************");  
            //Internet Protokoll Vers.2 == IPv4
            printf("\nInternet Protokoll Server:            %d", protokoll);  
            printf("\nIP-Adresse Server Konvertierung:      %d", partner_host_addr.sin_addr.s_addr); //1 beim Debuggen___ scheint korrekt umgesetzt zu werden??  
            printf("\nIP-Adresse Server:                    %s", "192.168.1.64");  
            printf("\nPort Server:                          %d", port);  
            printf("\nSocket:                               %d" ,sock);  
            printf("\n*******************************************************\n");  

            ip_address_fehler = host_addr.sin_addr.s_addr;

            if(ip_address_fehler == -1){

                printf("IP_Adresse nicht gefunden: %d", ip_address_fehler);  
                return 0;
            }

            rc = connect(sock, (struct sockaddr *)&host_addr, sizeof(host_addr));
            printf("\nVerbindung: %d", rc);  

            if(rc == SOCKET_ERROR){

                for(int i; i<=15; i++){

                    rc = connect(sock, (struct sockaddr *)&host_addr, sizeof(host_addr));
                    printf("\nErneut keine Verbindung: %d Verbindungsversuch %d", WSAGetLastError(), i);  
                    
                    /*Hier hängt sich das Script weg!*/
                    
                    sleep(1);

                    if(rc != -1){

                        break;
                    }
                }

                if(rc == SOCKET_ERROR){
                    exit(0);
                }
            }

            else{

                printf("Verbunden mit Server: 192.168.1.64");  

            }


        }

        /* Initialisiere TCP für Linux */
        else{

            return 0;

        }

        //Client Script beenden
        if(beenden == 0){

            printf("\n\nZum beenden bestätigen Sie mit 8:: ");  
            scanf("%d", &int_besteatigen);  

            if(int_besteatigen == 8){

                beenden = 1;
                exit(0);

            }
        }

        else{

            return 0;
        }

    }
}

Schon einmal vielen Dank für die Hilfe.

Gruß

Content-ID: 629359

Url: https://administrator.de/contentid/629359

Ausgedruckt am: 22.11.2024 um 11:11 Uhr

aqui
aqui 08.12.2020 um 17:52:08 Uhr
Goto Top
Sich gegenseitig pingen können aber beide Maschinen im Netz, oder ?
ParadisEOOO
ParadisEOOO 08.12.2020 um 17:57:23 Uhr
Goto Top
Hallo,

ja ein Ping funktioniert einwandfrei!
Habe vergessen zu erwähnen das meine VM (192.168.1.64) auf meinem normalen BS (Windows, 192.168.1.192) installiert ist.

Gruß
Pjordorf
Pjordorf 08.12.2020 um 18:34:34 Uhr
Goto Top
Hallo,

Zitat von @ParadisEOOO:
ich bin relativ neu in dem Thema und bräuchte hier einmal dringend Hilfe!
Bau in deinen Scripten doch einfach mal ein paar Variablen und Status ausgaben ein. Dann kannst du verfolgen wo was (nicht) passiert. Nennt sich Debuggen. Quellcode liegt dir ja vor.

Hier habe ich die Vermutung, das mein connect() nicht sauber läuft
Das verhalten deiner Scripte sollte reichen um eine vermutung deinerseits auszuschließen.

finde aber leider seit mehreren Tagen, keinen Ansatz dieses in den Griff zu bekommen.
Debuggen

Muss ich vor dem Starten der Scripte etwas beachten? Eventuell Portfreigaben?
Da keiner dein Netzwerk und Aufbau kennt kannst nur du wissen ob Portfreigaben/Portweiterleitungen nötig sind.

Gruß,
Peter
cykes
cykes 08.12.2020 um 19:54:26 Uhr
Goto Top
Nabend,

wenn Deiner Meinung nach der Server in der VM läuft, probier doch mal vor dem bereits erwähnten Debuggen einfach einen telnet <server-ip>:<port> - einmal direkt in der VM via localhost und zum anderen vom PC aus auf die IP, an die der Server gebunden ist.
Schmiert der Server dann nicht ab, läuft zumindest der.

Gruß

cykes
ParadisEOOO
ParadisEOOO 08.12.2020 um 22:14:45 Uhr
Goto Top
Müsste ich für einen Telnet, nicht den Port innerhalb des Scripts angeben??
Wenn ich Telnet als Server Port in meinem Script angebe, habe ich das Problem, dass der Port nicht mehr mit dem Socket gebunden werden kann. Hier scheitert dann mein bind() mit der Fehlermeldung 'Permission denied'.
Pjordorf
Pjordorf 09.12.2020 aktualisiert um 02:00:08 Uhr
Goto Top
Hallo,

Zitat von @ParadisEOOO:
Müsste ich für einen Telnet, nicht den Port innerhalb des Scripts angeben??
Schon mal was von einen Kommandofenster (CMD) oder Consolenfenster gehört und das man da drin dann telnat IP:Port eintippeln kann? Du kannst aber natürlich auch Telnet in dein Skript einbauen. Was ist jetzt einfacher?

Du hast von Debug oder ein Programm und Fehlersuche/behebung keinen Plan, oder?

Gruß,
Peter
maretz
maretz 09.12.2020 um 07:02:57 Uhr
Goto Top
Das mit Telnet macht man ja auch vom Client auf den Server...D.h. du startest deinen Server-Dienst, gehst auf den Client (oder irgendeinen anderen Rechner) und führst dort Telnet ip port aus -> und schaust ob er sich verbindet...

Ich würde allerdings auch zum Debuggen einfach nen paar Logging-Funktionen einbauen. Entweder über nen richtigen Logger oder über nen normales Kommando-Zeilen-Out (in Java wäre es nen System.out.println -> C++ is zu lange her, ich meine cout oder printf...). Da hängt es jetzt davon ab was du da vor hast - ist das nen reines Anfänger-Programm (also Tonnen-Programmierung - wenns mal läuft die Erkenntnisse fürs WIE mitgenommen, das Programm selbst geht in die Tonne) reicht ne Kommandozeilen-Ausgabe... Wenns was grösseres werden soll würde ich nen richtigen Logger nutzen...
cykes
cykes 09.12.2020 um 07:04:41 Uhr
Goto Top
... wobei mir bei genauerer Betrachtung gerade auffällt, dass der Server auch die winsock Libraries verwendet, was unter Linux natürlich wenig Sinn ergibt. Außer das kompilierte Programm läuft dann später unter Windows.

Woher hast Du denn den Code?
ParadisEOOO
ParadisEOOO 09.12.2020 um 16:26:26 Uhr
Goto Top
Hallo,

schon einmal vielen Dank für die vielen Antworten.

Zuerst mal...
@cykes
-den Code habe ich zum größten Teil selber für beide Anwendungen geschrieben.
Die Infos dazu habe ich von...
http://www.netzmafia.de/skripten/inetprog/inetprog1.html
-Das Script läuft für beide Anwendungen so, dass das OS beim einlesen der Libaries in einer variable festgehalten wird, und anhand der Variable, das Script und die passenden Libaries dann initialisiert werden.

@maretz
-Habe mich bei dem Portscan jetzt für nmap entschieden, hoffe dass ist auch okay. Ein Telnet scheitert permanent von Windowsseite aus. Auch auf bereits offene Port wie "192.168.1.64:10243"
-Ja genau das wird ein Anfängerscript fürs erste... Mein Vorhaben ist, dass die Ausgabe der Kommunikation von Ubuntu-Terminal zu Windows-CMD läuft.


Ich bin mittlerweile etwas weiter gekommen. Ich habe das Client Script jetzt einmal so umgeschrieben, dass es auch auf meiner VM läuft. Hier verbinden sich Client-Script und Server-Script problemlos.

Mein Ziel wäre es aber, dass die Anwendung von BS (Windows) zu Gastbetriebssystem(Ubuntu) läuft.
Hier einmal der pathping meiner Kommunikation. (Zu sehen ist das der ping direkt über die Netzwerkkarte auf die VM läuft)
kommunikationsablauf_pathping_win

Starte ich mein Server-Script auf Ubuntu, so wartet er über listen() auf eine Verbindung auf Port 7777.
Der Server wartet hier solange bis er eine Verbindung erkennt.
(Den Port habe ich jetzt einfach mal in beiden Scripten geändert)
Über netstat -ntl erhalte ich folgendes...
ubuntu_listen

Den Port habe ich ebenfalls vorher auf Ubuntu mit "sudo ufw allow 7777/tcp" freigegeben.
freigaben

Um nun Windowsseitig nachzuvollziehen, ob mein Port auch bei laufendem Serverscript offen ist, starte ich das Script auf Ubuntu und setze in Windows über "nmap -PN 192.168.1.64" einen Portscan.
nmap_on_open_ports_ubuntu

Hier erkennt Windows den geöffneten Port am Server aber nicht!?
Habt ihr hier einen weiteren Rat? Die Kommunikation scheint Windowsseitig also schon bei der Portabfrage zu scheitern!?

Führe ich danach mein Windows-Client-Script aus, bekomme ich wieder einen Fehler über connect()...
Connect gibt mir den Error "10047" zurück...
windows_connect

Ich werde vermutlich zu erst fertig bringen müssen, dass mein Port Scan sauber funktioniert, weiß aber leider nicht wie!?
Kennt hier jemand die Lösung?