Laden...

Netzwerkverbindung über Sockets/NetworkStream

Erstellt von bonzy vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.228 Views
bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren
Netzwerkverbindung über Sockets/NetworkStream

Hallo zusammen,

und zwar möchte ich wie im Topic angekündigt eine Verbindung über Sockets herstellen. Dazu gibt es im Netz zwar genug Tutorials, allerdings wird sich dort immer mit einer Verbindung zwischen Client und Server beschäftigt. Ich will allerdings direkt eine Verbindung zwischen zwei Clients herstellen, da so auch offline eine Verbindung möglich ist und mir außerdem kein Server zur Verfügung steht.
Über verschiedene Beispiele bin ich auf die Klassen Socket und NetworkStream gestoßen, mit denen ich auch schon eine Verbindung herstellen konnte. Allerdings macht mir die Übertragung zu schaffen, dort wäre ein wenig Hilfe nicht schlecht.
Allgemein bräuchte ich also Hilfe beim Senden und Empfangen von Daten über eine Client-Client-Verbindung, ob es nun auf Socket/NetworkStream hinausläuft oder nicht, ist mir dabei relativ egal, hauptsache es funktioniert gut, lasse mich da gerne von besseren Methoden überzeugen.

Bin dankbar für jede Hilfe. 😃

Gelöschter Account
vor 14 Jahren

du hast eine falsche vorstellung davon, was ein server und ein client ist. server aus programmiertechnischer sicht ist derjenige der auf eingehende verbindungsanfragen lauscht.

daher passen sämtliche tutorials auch für dein vorhaben.

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Also wären bei einer Verbindung zwischen zwei Rechnern beide sowohl Client als auch Server, da sie sowohl Senden als auch Empfangen können. Ich denke mit dem Wissen werde ich dann mal weiterschauen.

Gelöschter Account
vor 14 Jahren

ja und nein. senden und empfangen hat erstmal ncihts mit der tatsache zu tun ob jemand client ist oder server. senden und empfangen tut man über eine hergestellte verbindung. nur die art und weise, wie die verbindung zustandekommt deklariert den einen zum server und den anderen zum client. selbstverständlich kann ein programm beides gleichzeitig sein, muss es aber nciht.

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Also wäre es egal, wer Server und wer Client ist, da beide sowohl Senden als auch Empfangen können? Es käme nur darauf an, wer die Verbindung hergestellt hat?
Wie genau ist denn der Ablauf beim Senden und Empfangen? So wie ich es verstanden habe sendet der Client etwas an den Server, dieser empfängt die Daten und schickt etwas an den Sender zurück. Dabei kann der Server aber nicht von sich aus einen Client ansprechen oder?

4.942 Beiträge seit 2008
vor 14 Jahren

Am besten, du erstellst ein Programm, daß sowohl als Client als auch als Server fungieren kann, d.h. sowohl Socket.Listen/Socket.Accept als auch Socket.Connect verwendet (in verschiedenen Methoden - versteht sich).

Und da die Socket.Accept-Methode selber wieder einen Socket zurückgibt, kann auch der Server aktiv an den Client (bzw. die Clients, wenn diese dann z.B. in einer List<Socket> gespeichert sind) Daten senden.

Gelöschter Account
vor 14 Jahren

Also wäre es egal, wer Server und wer Client ist, da beide sowohl Senden als auch Empfangen können?

jap

Es käme nur darauf an, wer die Verbindung hergestellt hat?

das ist ja egal 😃 hauptsache irgendeiner spielt den server.

Wie genau ist denn der Ablauf beim Senden und Empfangen?

grob definiert:

  1. server fängt an auf einem port zu horchen
  2. client fragt an IP:port an, ob da wer horcht
  3. server bekommt anfrage und gibt seine daten durch
  4. client bekommt antwort und gibt seine daten durch
  5. verbindung steht.

nun weiß der server das es einen client gibt und kann ihm was senden.
nun weiß der client, das der server da ist und kann ihm was senden.

das ganze geht dann über die bereits genannten socket klassen.

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Die Erklärung hilft mir sehr, danke dafür. Eine Frage hätte ich jetzt noch: Kann ein Socket-Objekt parallel Senden und Empfangen oder braucht man dafür zwei?

Gelöschter Account
vor 14 Jahren

es kann sowohl senden als auch empfangen. (soweit ich das in errinnerung habe)

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Das Problem bei mir ist gerade, dass ich zwar von einer Seite aus senden kann und von der anderen empfangen, aber nicht beides.

Eventuell hilft ja der Quellcode weiter, hoffe es ist nicht zu viel.

Edit: Habe es schon hinbekommen, danke nochmal.

using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;

namespace snake
{
    public class Network
    {
        private System.Net.IPEndPoint inputEndPoint;
        private System.Net.IPEndPoint outputEndPoint;

        private Socket listenSocket;
        private Socket acceptSocket;
        private Socket outputSocket;

        private const int port = 2208;

        public void InitNetwork(string ipAdress)
        {
            if (this.acceptSocket != null && this.acceptSocket.Connected)
            {
                this.acceptSocket.Close();
            }

            this.outputEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse(ipAdress), port); 

            this.acceptSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            this.Connect();
        }

        public void InitNetwork()
        {
            if (this.listenSocket != null) return;

            this.inputEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, port);

            this.listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            this.listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);

            this.listenSocket.Bind(this.inputEndPoint);

            this.listenSocket.Listen(1);

            this.listenSocket.BeginAccept(new AsyncCallback(AcceptMessage), null);
        }

        private void Connect()
        {
            try
            {
                this.acceptSocket.BeginConnect(this.outputEndPoint, null, null);
            }
            catch
            {
                this.ErrorMessage("Connection failed");
            }
        }

        private void ErrorMessage(string message)
        {
            System.Windows.Forms.MessageBox.Show(message, "Error",
                System.Windows.Forms.MessageBoxButtons.OK,
                System.Windows.Forms.MessageBoxIcon.Error);
        }

        public void SendMessage(string message)
        {
            this.acceptSocket.Send(System.Text.Encoding.ASCII.GetBytes(message));
        }

        public void SendMessage(IAsyncResult result)
        {
            this.listenSocket.EndSend(result);
        }

        public void AcceptMessage(IAsyncResult result)
        {
            this.acceptSocket = this.listenSocket.EndAccept(result);

            byte[] buffer = new byte[4096];

            this.acceptSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
                new AsyncCallback(this.ReceiveMessage), buffer);
        }

        public void ReceiveMessage(IAsyncResult result)
        {
            try
            {
                this.acceptSocket.EndReceive(result);
            }
            catch
            {
                this.ErrorMessage("Connection abrupted");
                return;
            }

            this.OnNewMessage(System.Text.Encoding.ASCII.GetString((byte[])result.AsyncState));

            byte[] buffer = new byte[4096];

            this.acceptSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
                new AsyncCallback(this.ReceiveMessage), buffer);
        }

        ~Network()
        {
            if (this.listenSocket != null && this.listenSocket.Connected)
            {
                this.listenSocket.Close();
            }
        }

        private void OnNewMessage(string message)
        {
            this.NewMessage.Invoke(message);
        }

        public delegate void NewMessageEventHandler(string message);

        public event NewMessageEventHandler NewMessage;
    }
}
3.728 Beiträge seit 2005
vor 14 Jahren

Ich will allerdings direkt eine Verbindung zwischen zwei Clients herstellen, da so auch offline eine Verbindung möglich ist und mir außerdem kein Server zur Verfügung steht.

Das ist ein Widerspruch! Wenn ein Rechner offline ist, hat er keine Netzwerkverbindung und kann dann garnicht übers Netzwerk kommunizieren. Der Begriff Server und Client meint die Rollen der einzelnen Systeme bei der Netzwerkkommunikation. Häufig wird bestimmte Funktionalität auf einem zentralen Computer zur Verfügung gestellt. Dieser Computer wird dann als Server bezeichnet (auch wenn er als Betriebssystem Windows XP Home installiert hat). Es gibt auch verteilte Anwendungen, bei denen alle Kommunikationsteilnehmer weitgehend gleichberechtigt sind. Man spricht dann von Peer-to-Peer, statt von Client-Server.

Warum willst Du überhaupt direkt mit Sockets arbeiten. Das ist in den allermeisten Fällen absoluter Unsinn. Das .NET Framework bietet verschiedene fertige Kommunikations-Implementierungen an, die viel einfacher zu nutzen sind. Das wären:*.NET Remoting *WCF *ASP.NET Webdienste *Microsoft Message Queuing *Enterprise Services

Wahrscheinlich kannst Du Dein Problem mit einer dieser Technologien viel besser lösen, als alles mit Sockets zu Fuß zu entwickeln.

Was willst Du denn genau für eine Anwendung schreiben?
Was soll am Ende dabei herauskommen?

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Ich habe relativ oft was über Sockets gefunden, daher dachte ich eben, dass das wohl eine Methode sei, mit der man öfters arbeitet. Und mit "offline" meinte ich nicht mit dem Internet verbunden, war vielleicht etwas schlecht formuliert.

Aber wie oben zu lesen:

Edit: Habe es schon hinbekommen, danke nochmal.

Von daher danke für die kleine zusätzliche Erläuterung, aber ich habe bereits Fortschritte gemacht. Im Moment hakts nur noch ein wenig am Finetuning, aber das liegt weniger an der Kommunikations-Technologie.

Die "Anwendung" ist eigentlich nur eine Klasse, die ich dann in einem Spiel benutze, um auch übers Netzwerk einen Multiplayer zu ermöglichen.

Wenns dich interessiert -> Snake