Nätverkskommunikation
Nätverksprotokoll För att datorer ska kunna kommunicera med varandra behövs någon sort av regler för hur kommunikationen ska gå till. Reglerna kallas för protokoll i sådana sammanhang. Det finns ett antal protokoll men det är TCP/IP som är dominant i dagsläge för nätverkskommunikation IP – Internet Protocol Protokoll för Internet kommunikation TCP – Transmission Control Protocol Protokoll för sändning över Internet Tillåter upprätthållande av virtuella kanaler över Internet i vilka information kan enkelt skickas.
Adressering Med adressering menas att: ange adressen till värddatorn med hjälp av IP adress. ange portnummer som ska anslutas till. Adressering åstadkoms med hjälp av dessa klasser: IPAddress: representerar en IP adress IPEndPoint: representerar en IP adress och ett portnummer till vilken datorn den ska kopplas till. IPAddress och IPEndPoint finns I namnrymden System.Net IPAddress ipAdr = new IPAddress(192121049001); IPEndPoint ipEP = new IPEndPoint(ipAdr, 80);
IPAddress Klassen IPAddress används till att representera just en IP adress. IPAddress har ett antal överlagrade konstruktorer: IPAddress iPa1 = new IPAddress(192000000001); IPAddress iPa2 = new IPAddress(new byte[] {192,0,0,1}); IPAddress har en egenskap(property) för att returnera IP adressen till den aktuella datorn. IPAddress.Loopback
Kommunikation via Socket, översikt .NET Remoting och Webservices använder Socket för att upprätthålla kommunikationen via nätverket. Vid kommunikation via nätverket en av parterna måste initiera kommunikationen. Klient och server har olika uppgifter och är vanligtvis placerade i olika applikationer. När en anslutning har upprätthållits mellan två Sockets och kommunikationen har påbörjat, både parterna har då samma möjlighet för kommunikation
Kommunikation via Socket Socket representerar tvåvägskommunikations kanaler, som tillåter att både skicka och ta emot strömmade data. Klient-Server arkitektur Klient sänder förfrågning till Servern Server bearbetar förfrågningen och Skickar svaret tillbaka Adresseringen sker med hjälp av IP adress och portnummer Informationsbyte sker via strömmar (nätverksströmmar) 15 80 ... 152.153.5.204 Data Internet Server Client
System.Net.Sockets Namnrymden System.Net.Sockets tillhandahåller en säker implementation av interfacet Windows Sockets (Winsock) så at utvecklarna som behöver ha kontroll över tillträde till nätverket får det. Följande klasser finns i System.Net.Sockets: NetworkStream Socket TcpClient TcpListener UdpClient ….. Följande enumerationer finns i System.Net.Sockets: ProtocolType SocketShotdown
Socket Klassen Socket tillhandahåller en rik uppsättning av metoder och egenskaper för nätverkskommunikation. Klassen Socket tillåter att genomföra både synkrona som asynkrona dataöverföring med hjälp av någon kommunikations protokoll som är listade i en enumeration som heter ProtocolType. ProtocolType enumerationen används av Socket för att informera Windows Socket API vilka protokoll som finns och kan användas. public enum ProtocolType {Ggp, Icmp, Idp, IP, IPv6, Tcp, UDP, ……. }
Socket Om ett protokoll som TCP används: Servern kan lyssna då på anslutningen genom metoden Listen. Metoden Bind måste anropas före metoden Listen för att specificera IP adress och portnummer den ska kopplas till. Metoden Accept bearbetar inkommande förfrågningar och returnerar ett Socketobjekt som används till att kommunicera med klienten . Servern använder den returnerade Socketobjektet till att anropa metoderna Send och Receive. Om en klient vill koppla sig till en server som lyssnar, anropa då metoden Connect. För att klienten ska kommunicera med servern, anropa då metoderna Send och Receive.
Socket Server Klient Socket s0 = new Socket(); IPAddress ip = IPAddress.parse(192.1.1.0); IPEndPoint ep = new IPEndPoint(ip,5000); s0.bind(ep); s0.Listen(10); Server Skapa en Socket och binda den till IP adress och portnummer Öppna Socket för maximal 10 klienter Klient Skapa en Socket och binda den till IP adress och portnummer Socket s2 = new Socket(); IPAddress ip = IPAddress.Parse(192.1.1.0); IPEndPoint ep = new IPEndPoint(ip,5000); 5000 … s0 Server s2 Client
Socket Väntar på anslutningen Anslut till servern Socket s1 = s0.Accept(); s2.Connect(ep); s2 Client 5000 … s0 Server s1 Kommunicera med klienten och avbryt anslutningen Kommunicera med servern och avbryt anslutningen s1.Receive(msg1); ... s1.Send(msg2); s1.Shutdown(SocketShutdown.Both); s1.Close(); s2.Send(msg1); ... s2.Receive(msg2); s2.Shutdown(SocketShutdown.Both); s2.Close();
Exempel på EchoServer EchoClient_1 EchoServer EchoClient_N Implementera en enkel klient-server applikation. EchoServer accepterar godtyckligt data från klienten och returnerar datat oförändrat tillbaka till klienten. EchoServer EchoClient_1 EchoClient_N Port 5000 „test echo“ „hello“
Exempel på EchoServer class EchoServer { socket s; public bool StartUp(IPAddress ip, int port) try s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Bind(new IPEndPoint(ip, port)); s.Listen(10); // Maximal 10 klienter } catch (Exception e) { ... } for(;;) // vänta på anslutningen Communicate(s.Accept());
Exempel på EchoServer, forsättning class EchoServer { ... // Returnerar tillbaka datat till klienten public void Communicate(Socket clSock) try byte[] buffer = new byte[1024]; while (clSock.Receive(buffer) > 0) // ta emot data clSock.Send(buffer); // skicka tillbaka data clSock.Shutdown(SocketShutdown.Both); // stänga socket clSock.Close(); } catch (Exception e) { ... } } public static void Main() EchoServer = new EchoServer(); server.StartUp(IPAddress.Loopback, 5000); // Starta echo server
Exempel på EchoClient class EchoClient { ... public static void Main() try // Anslut till server Socket s = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); s.Connect(new IPEndPoint(IPAddress.Loopback, 5000)); s.Send( Encoding.ASCII.GetBytes("This is a test“)); // skicka meddelande byte[] echo = new byte[1024]; s.Receive(echo); // ta emot echo meddelande Console.WriteLine(Encoding.ASCII.GetString(echo)); } catch (Exception e) { ... }
Socket kommunikation med TCP/IP Om man utvecklar en relativ enkel applikation som kräver ingen hög prestanda, då ska man överväga att använda TcpClient och TcpListener. Dessa klasser tillhandahåller en enklare och mer användarvänligt gränssnitt mot Socket kommunikation.
TcpClient Klassen TcpClient tillhandahåller enkla metoder för att ansluta, skicka och ta emot en ström av data över nätverket, synkront. Om man ska använda TcpClient till att ansluta och utbyta data, så måste servern lyssna på inkommande förfrågningar med hjälp av TcpListener eller Socket. Det går att ansluta till dessa lyssnare i en av följande sätt: Skapa en TcpClient och anropa en av dess 3 tillgängliga Connect metoderna. Skapa en TcpClient genom att ange datornamnet och portnummer på fjärrdatorn. konstruktorn skapar då automatiskt en anslutning. Att skicka eller ta emot data använd metoden GetStream för att erhålla NetworkStream. Anropa metoderna Write och Read med hjälp av NetworkStream-objektet Använd metoden Close för att frigöra alla resurser som är kopplade till TcpClient.
TcpClient public class SocketClient { public static void Main() try TcpClient tcpc = new TcpClient(); tcpc.Connect(IPAddress.Loopback, 5000); StreamWriter sw = new StreamWriter(tcpc.GetStream()); StreamReader sr = new StreamReader(tcpc.GetStream()); sw.Write(“Hello server“); MessageBox.Show(sr.ReadLine()); sw.Close(); sr.Close(); tcpc.Close(); } catch (Exception e) { ... }
TcpListener Klassen TcpListener tillhandahåller enkla metoder som lyssnar och godkänner de inkommande förfrågningar. Det går att använda TcpClient eller Socket för att ansluta till TcpListener. TcpListener skapas med hjälp av en av dess 3 konstruktorer: TcpListener(IPEndPoint) TcpListener(IPAddress,portnummer) TcpListener(portnummer)
TcpListener Använd metoden Start till att börja lyssna på inkommande förfrågningar. Start sätter de inkommande förfrågningar i ett kösystem tills man anropar metoden Stop eller tills att kön har uppnåtts dess maximala storlek. Använd antigen AcceptSocket eller AcceptTcpClient till att plocka en anslutning från kön. Dessa två metoder blockerar. För att undvika blockeringen använd först metoden Pending för att avgöra om en förfrågning om anslutning finns i kön.
TcpListener public class SocketServer { public static void Main() try TcpListener tcpl = new TcpListener(IPAddress.Loopback, 5000); tcpl.Start(); if (! tcpl.Pending()) Console.WriteLine("Sorry, no connection requests have arrived"); } else TcpClient client = tcpl.AcceptTcpClient(); StreamWriter sw = new StreamWriter(tcpc.GetStream()); sw.Write(“Hello Client“); sw.Close(); client.Close(); tcpl.Close(); catch (Exception e) { ... }
NetworkStream Klassen NetworkStream tillhandahåller metoder för att skicka och ta emot data över Socket. Det måste finnas en ansluten Socket för att skapa en NetworkStream. Socket s = new Socket(); s.Connect(”www.isk.kth.se”, 4711); NetworkStream ns = new NetworkStream(s);
NetworkStream Efter att NetworkStream-objektet har initierats då går att skicka och ta emot data via dessa två metoder: Write Read Socket s = new Socket(); s.Connect(”www.isk.kth.se”, 4711); NetworkStream ns = new NetworkStream(s); byte[] myWriteBuffer = Encoding.ASCII.GetBytes(”Hello .NET"); s.Write(myWriteBuffer, 0, myWriteBuffer.Length); byte[] myReadBuffer = new byte[1024]; s.Read(myReadBuffer, 0, myReadBuffer.Length);
StreamWriter & StreamReader Om man har en ström, som NetworkStream, kan man då använda klasserna StreamWriter och StreamReader (System.IO) för att enkelt skriva och läsa text på strömmen. StreamWriter output = new StreamWriter (ns); output.WriteLine(“Hello .NET”); output.Flush(); En StreamWriter har metoderna Write och WriteLine som fungerar precis som motsvarande statiska metoder i Console-klassen. På detta sätt kan man alltså skicka formaterade text-meddelanden med inkluderade variabelvärden. Write- och WriteLine-metoderna skriver meddelanden på strömmen men för att även skicka iväg dem måste man anropa output.Flush(). stänga StreamWriter-objektet med output.Close() stänga ned TcpClient-objektet och det måste ändå göras till slut så i de flesta fall behöver Close-metoden inte användas.
StreamWriter & StreamReader StreamReader input = new StreamReader (ns); MessageBox.Show(input.ReadLine()); StreamReader har metoderna Read och ReadLine som fungerar precis som motsvarande metoder i Console-klassen men de läser från nätverksströmmen istället för från standard in. Det finns fler läsmetoder i klassen som du kan läsa om i klassbiblioteksreferensen om du är intresserad.