Winsock Visual Studio 2010 GUI usw.



  • Hallo erstmal

    Ich möchte einen Code für eine Win32 Konsolen Anwendung den ich mal geschrieben habe in ein Visual C++ Anwendung "einbinden".
    Als Entwicklungsumgebung benutze ich Visual Studio 2010 Express.
    Ich habe eine GUI mit dem Toolkit von Visual Studio erstellt.
    Wenn ich jetzt die Datei dem Projekt hinzufüge(header) und die Funktion aufrufe kommen Fehler wie WSAStartup: Bezeichner wurde nicht gefunden oder wsa verwendent undefiniertes struct WSAData. -> Es ist eine Winsock Anwendung
    Der generierte Code vom GUI ist Objektorientiert könnte das ein Problem sein ?
    Weis jemand was ich falsch mache ?

    Gruss h0m3r J S



  • 1. überprüf mal deine include-angaben. (oder zeig code her)
    2. die stdafx.h sollte oben stehen.
    3. welchen fehler gibts genau?



  • Hier ein paar Fehler die ausgegeben werden:

    error C2039: 'sin_addr': Ist kein Element von 'System::Int32'
    error C2228: Links von ".S_un" muss sich eine Klasse/Struktur/Union befinden.
    error C2228: Links von ".S_addr" muss sich eine Klasse/Struktur/Union befinden.
    error C3861: "inet_addr": Bezeichner wurde nicht gefunden.
    error C2440: '=': 'int (__clrcall *)(SOCKET,const sockaddr *,int)' kann nicht in 'long' konvertiert werden
    error C3861: "connect": Bezeichner wurde nicht gefunden.
    error C2079: 'wsa' verwendet undefiniertes struct 'WSAData'
    error C3861: "WSAStartup": Bezeichner wurde nicht gefunden.
    1>  Code wird generiert...
    

    Hier die Header Datei:

    #pragma comment( lib, "ws2_32.lib" )
    #include "stdafx.h"
    #include "Form1.h"
    #include <Windows.h>
    #include <WinSock2.h>
    #include <iostream>
    
    int winsock()
    {
    	long rc;
    	SOCKET s;
    	SOCKADDR_IN addr;
    
    	rc = startWinsock();
    	if(rc != 0)
    	{
    		// WInsock konnte nicht gestartet werden ...
    	}
    
    	else
    	{
    		//WSock gestartet
    	}
    	s = socket(AF_INET, SOCK_STREAM, 0);
    	if(s == INVALID_SOCKET)
    	{// 
    	}
    
    	else
    	{
    	}
    	memset(&addr, 0, sizeof(SOCKADDR_IN));
    	addr.sin_family = AF_INET;
    	addr.sin_port = htons(10000);
    	addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    	rc = connect (s, (SOCKADDR*)&addr, sizeof(SOCKADDR));
    	if(rc == SOCKET_ERROR)
    	{
    		// Fehler
    
    	else
    	{
    		// Verbunden mit ... Ausgeben
    	}
    	std::cin.get();
    	return 0;
    }
    
    int startWinsock(void)
    {
    	WSADATA wsa;
    	return WSAStartup(MAKEWORD(2, 0), &wsa);
    
    }
    


  • Was wird das C++/CLI?



  • Martin Richter schrieb:

    Was wird das C++/CLI?

    Ich möchte nur meinen alten Code (Konsolenanwendung) in eine WIndows Forms Anwendung einbinden.



  • h0m3r J S schrieb:

    Martin Richter schrieb:

    Was wird das C++/CLI?

    Ich möchte nur meinen alten Code (Konsolenanwendung) in eine WIndows Forms Anwendung einbinden.

    Warum sollte das jmd. tun wollen?
    Ist doch Unsinn...



  • theta schrieb:

    h0m3r J S schrieb:

    Martin Richter schrieb:

    Was wird das C++/CLI?

    Ich möchte nur meinen alten Code (Konsolenanwendung) in eine WIndows Forms Anwendung einbinden.

    Warum sollte das jmd. tun wollen?

    Wieso fragst du mich ?



  • Wie könnte man es dann mit Windows Forms und Winsock machen ?

    Gruss H0mer



  • Entweder Windows Forms (--> .NET) mit C# oder Winsock (native) mit irgendeinem anderem (nativen) GUI Toolkit.

    Nicht managed und unmanaged mischen. Das führt zu Problemen, die Du nicht hättest, wenn Du nicht mischen würdest.



  • Könnte man nicht ne lib schreiben und die in das WinForms Projekt einbinden?



  • @ Admin/ Moderator Bitte ins C#/ .net Forum verschieben.

    @ cooky451/ theta: Ich weis nicht, ich hab mich jetzt entschieden es mit C# zu lösen. Danke für eure Hilfe !!

    Jetzt habe ich noch eine andere Frage bezüglich dieses Codes:

    Server:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using ConsoleApplication1;
    using System.Windows.Forms;
    
    namespace beginSocketServer
    {
        //FILE TRANSFER USING C#.NET SOCKET - SERVER
        class Program
        {
            static void Main(string[] args)
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
                try
                {
                    IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, port);
                    Socket sock = newSocket(AddressFamily.InterNetwork,             SocketType.Stream, ProtocolType.IP);
                    sock.Bind(ipEnd);
    
                        sock.Listen(100);
                        Socket clientSock = sock.Accept();
    
                        string fileName = "Archive.zip";// File";
                        string filePath = @"E:\";//File Pfad;
                        byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
    
                        byte[] fileData = File.ReadAllBytes(filePath + fileName);
                        byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
                        byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
    
                        fileNameLen.CopyTo(clientData, 0);
                        fileNameByte.CopyTo(clientData, 4);
                        fileData.CopyTo(clientData, 4 + fileNameByte.Length);
    
                        clientSock.Send(clientData);
                        Console.WriteLine("File:{0} has been sent.", fileName);
                        Console.ReadLine();
    
                        clientSock.Close();
                        Console.ReadLine();
                    }
    
                catch (Exception ex)
                {
                    Console.WriteLine("File Receiving fail." + ex.Message);
                    Console.ReadLine();
                }
             }
            }
        }
        }
    

    Client:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Configuration;
    using System.Windows.Forms;
    using ConsoleApplication1;
    using System.Diagnostics;
    
    namespace Client_Socket
    {
        //FILE TRANSFER USING C#.NET SOCKET - CLIENT
        class Program
        {
            static void Main(string[] args)
            {
    
                String ip = "";
                int port = 0;  
    
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
    
                AppSettingsReader config = new AppSettingsReader();
                port = (int)config.GetValue("Port", typeof(int));
                ip = (String)config.GetValue("IpSrV", typeof(String));
    
                    try
                    {
                        IPAddress[] ipAddress = Dns.GetHostAddresses(ip);
                        IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], port);
                        Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                        clientSock.Connect(ipEnd);
    
                        byte[] clientData = new byte[1024 * 5000];
                        string receivedPath = "E:\\TestPfad\";
    
                        int receivedBytesLen = clientSock.Receive(clientData);
    
                        int fileNameLen = BitConverter.ToInt32(clientData, 0);
                        string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
    
                        Console.WriteLine("Client: connected", clientSock.RemoteEndPoint, fileName);
                        Console.ReadLine();
    
                        BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append)); ;
                        bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
    
                        Console.WriteLine("File: empfangen & gespeichert", fileName, receivedPath);
                        Console.ReadLine();
    
                        bWrite.Close();
                        clientSock.Close();
                        Console.ReadLine();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("übertragung fehlgeschlagen." + ex.Message);
                        Console.ReadLine();
                    }
    
            }
        }
    }
    

    Ist der Code OK (Er funktioniert mit 1 Client )?
    Wie könnte ich es mit mehreren Clients lösen? (For Schleife, TcpEchoServerAsync)

    Gruss H0mer



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum WinAPI in das Forum C# und .NET verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Hat noch niemand etwas gefunden 😕
    Wie kann ich es mit meheren Clients machen ?

    Gruss H0mer


  • Administrator

    H0Mer schrieb:

    Ist der Code OK (Er funktioniert mit 1 Client )?

    Geht so ...
    1. Wieso das Application.Run am Anfang? Application.Run blockiert, bist Form1 beendet wurde. Ist das wirklich gewollt?
    2. Schon mal was von TcpClient und TcpListener gehört?
    3. ... naja ...

    Scheint im groben zu stimmen, keine Lust dies jetzt genauer zu analysieren.

    H0Mer schrieb:

    Wie könnte ich es mit mehreren Clients lösen? (For Schleife, TcpEchoServerAsync)

    Für eine parallele Kommunikation brauchst du auf der Serverseite einen Thread für jeden Client. Du aktzeptierst die Verbindung und startest einen neuen Thread, dem du das Socket übergibst.

    Könntest du deine Fragen ein wenig präzisieren? Wo drückt denn der Schuh? Wo hast du Probleme mit mehreren Clients? Hast du es schon mal versucht? Oder einfach keinen Plan?

    Grüssli



  • Dravere schrieb:

    H0Mer schrieb:

    Ist der Code OK (Er funktioniert mit 1 Client )?

    Geht so ...
    1. Wieso das Application.Run am Anfang? Application.Run blockiert, bist Form1 beendet wurde. Ist das wirklich gewollt?
    2. Schon mal was von TcpClient und TcpListener gehört?
    3. ... naja ...

    Scheint im groben zu stimmen, keine Lust dies jetzt genauer zu analysieren.

    H0Mer schrieb:

    Wie könnte ich es mit mehreren Clients lösen? (For Schleife, TcpEchoServerAsync)

    Für eine parallele Kommunikation brauchst du auf der Serverseite einen Thread für jeden Client. Du aktzeptierst die Verbindung und startest einen neuen Thread, dem du das Socket übergibst.

    Könntest du deine Fragen ein wenig präzisieren? Wo drückt denn der Schuh? Wo hast du Probleme mit mehreren Clients? Hast du es schon mal versucht? Oder einfach keinen Plan?

    Grüssli

    Zu Application.run : Ja ich habe gemerkt das es wartet bis das Formular geschlossen wurden, was sollte ich den stattdessen benutzen?

    Für jeden Client einen neuen Thread, was wenn ich nicht weis wie viele Clients es gibt?
    Einen Thread zu erstellen wenn ein Client sich "verbindent" ?

    Mit den mehreren Clients habe ich es Versucht, zum Beispiel mit einer Endlos For schleife (Keine Gute Idee) kommt ab dem 2 Client ein Fehler.
    (Verbindung kann nur einmal genutzt werden, oder so ...)

    Der Server soll übrigens die GANZE(24h) Zeit auf Clients warten !!!
    Fühle mich deswegen so Unsicher -> Stürtzt es ab? Kommen ab bestimmten Anzahl Clients Fehler ? usw.

    Danke noch für deine Tipps !!!

    Gruss H0mer



  • OK, ich habs mit mehreren Clients geschafft nun will ich aber grössere Datein Versenden.
    Mit dem Code den ich gepostet habe gehts glaub ich nur mit bis zu 840kb.
    Sollte ich es mit einer Schleife senden und empfangen , also zuerst Dateigrösse senden, und überprüfen ob alles angekommen ist.
    ca. 10MB sollten schon möglich sein.
    Beipiel:

    for(int i=0; i<size; i++){

    socket.send(buffer, size, SocketFlags.None);
    }

    Das gleiche beim Client (Natürlich mit Recieve :-))

    Gibt es noch etwas bezüglich Sicherheit die man bei Sockets beachten sollte?
    Was muss ich tun damit das Programm möglichst Stabil läuft, am besten nie Abstürzt ?

    Noch eine Frage zu C#:

    Was ist sollte man benutzen?

    using System.Windows.Forms;

    MessageBox.Show("BlaBla");

    oder

    System.Windows.Forms.MessageBox.Show("BlaBla");

    Gruss H0mer

    ps. ich habe nicht so auf die Syntax geachtet 🙂



  • Ich habe nicht den gesamten Thread verfolgt und auch keine große Lust irgendwelche Codes zu analysieren.

    H0mer schrieb:

    Noch eine Frage zu C#:

    Was ist sollte man benutzen?

    using System.Windows.Forms;

    MessageBox.Show("BlaBla");

    oder

    System.Windows.Forms.MessageBox.Show("BlaBla");

    Man sollte durchaus using nutzen, um sich damit unnötige Tipparbeit zu sparen. Dadurch wird auch die Lesbarkeit gesteigert, da man weniger Text (=Code) erfassen muss. Damit ist also die erste Variante um einiges besser. Das sollte dir bei genauerer Betrachtung auch selber auffallen.

    Ansonsten ist es sinnig, wenn man dem Client die Länge in Bytes sendet. Dieser liest dann so lange bis er diese Anzahl von Bytes empfangen hat. Dazu ist natürlich eine Schleife notwendig.

    Alternativ kannst du das ganze auch in eine Art Protokoll verfassen.

    Das kann dann so aussehen:

    CLI_FILE_SEND_START Test.txt\n
    SRV_FILE_ACCEPT\n
    CLI_FILE_SEND_BLOCK 1024\n
    <1024 Bytes>
    SRV_FILE_BLOCK_OK\n
    CLI_FILE_SEND_BLOCK 15\n
    <15 Bytes>
    SRV_FILE_BLOCK_OK\n
    CLI_FILE_SEND_DONE\n

    Zunächst sendet der Client den Befehl, dass er eine Datei namens Test.txt übertragen möchte. Anschließend wird der erste Block der Größe 1024 Byte übertragen. Danach sendet der Client einen weiteren Block, welcher nur noch 15 Byte groß ist. Wenn der Client auch diesen empfangen hat, dann wird der Sendevorgang mit FILE_SEND_DONE bestätigt und abgeschlossen. Der Server bestätigt die Anfragen natürlich auch.

    Im Prinzip könnte man jedem Block auch ein Hash mitgeben, um sicherzustellen, dass die Daten korrekt übertragen wurden. Aber grundsätzlich dürfte es da keine Probleme geben (TCP).


  • Administrator

    H0mer schrieb:

    Zu Application.run : Ja ich habe gemerkt das es wartet bis das Formular geschlossen wurden, was sollte ich den stattdessen benutzen?

    Kommt ganz darauf an, was du machen möchtest. Braucht der Server denn ein GUI? Dann kannst du auf Events im GUI reagieren und dort dann einen Server-Thread starten lassen. Wenn das GUI geschlossen wird, reagierst du wieder auf dieses Event und kommunizierst das weiter zum Server-Thread, welcher dann den Server schliesst. Ist zum Beispiel eine mögliche Lösung, aber hängt eben ganz von den Anforderungen ab.

    H0mer schrieb:

    Einen Thread zu erstellen wenn ein Client sich "verbindent" ?

    Genau. Kannst ja auch einen ThreadPool verwenden.

    H0mer schrieb:

    Gibt es noch etwas bezüglich Sicherheit die man bei Sockets beachten sollte?

    Was verstehst du unter Sicherheit? Absturzsicherheit oder Verschlüsselung, Angreiferschutz co?

    H0mer schrieb:

    Fühle mich deswegen so Unsicher -> Stürtzt es ab? Kommen ab bestimmten Anzahl Clients Fehler ? usw.

    H0mer schrieb:

    Was muss ich tun damit das Programm möglichst Stabil läuft, am besten nie Abstürzt ?

    Es ist schwer auf solche Fragen eine Antwort zu geben, denn sie sind viel zu allgemein. Weshalb man fast nur mit allgemeinen Antworten antworten kann: "Programmier korrekt und ohne Fehler!"
    Lies halt die jeweiligen Dokumentationen, informier dich über das Thema. Vielleicht kannst du auch mal ein Buch zur Socket-Programmierung kaufen, da stehen viele Tipps drin. Frag mich aber jetzt bitte nicht, nach einem guten Buch, da wäre ich überfragt 🙂

    sdfsdfs schrieb:

    Zunächst sendet der Client den Befehl, dass er eine Datei namens Test.txt übertragen möchte. Anschließend wird der erste Block der Größe 1024 Byte übertragen. Danach sendet der Client einen weiteren Block, welcher nur noch 15 Byte groß ist. Wenn der Client auch diesen empfangen hat, dann wird der Sendevorgang mit FILE_SEND_DONE bestätigt und abgeschlossen. Der Server bestätigt die Anfragen natürlich auch.

    Im Prinzip könnte man jedem Block auch ein Hash mitgeben, um sicherzustellen, dass die Daten korrekt übertragen wurden. Aber grundsätzlich dürfte es da keine Probleme geben (TCP).

    Die jeweiligen OKs erscheinen mir in deinem Protokoll überflüssig. TCP sendet intern schon ein OK, ob es den gesendeten Block erhalten hat. Ein Send Aufruf gibt somit sowieso erst zurück, wenn der Datenblock erfolgreich übermittel wurde.

    Grüssli



  • Hier noch der Code: Mit Thread(GUI + Sockets) und File Senden Empfangen

    Server:

    public static void Requests()
            {
    
                Socket listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listenSock.Bind(new IPEndPoint(IPAddress.Any, 9999));
                listenSock.Listen(20);
    
                while (true)
                {
                    using (Socket newConnection = listenSock.Accept())
                    {
                        ...
    
    // File Senden :  
                          for (int i = 0; i < size; i+= tr)
                          {
    
                                   tr = newConnection.Send(mfile,i , size - i, SocketFlags.None);
                          }
    
    ...
    
                    }
                }
            }
    
            static void Main()
            {
    
                Thread listener = new Thread(new ThreadStart(Requests));
                listener.IsBackground = true;
                listener.Start();
    
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FServer());
            }
    

    Client:

    ...
    
                        for (int i = 0; i < size; i += re)
                        {
                              re = s.Receive(mfile, i, size - i, SocketFlags.None);
                        }
    
                        File.WriteAllBytes(@"pfad\Archiv.zip", mfile);
    ...
    

    Ist er Gut oder nicht oder gar nicht ?

    GRuss H0mer


Log in to reply