全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1844
推到 Plurk!
推到 Facebook!

UDP (User Datagram Protocol)

 
AB
高階會員


發表:166
回覆:262
積分:125
註冊:2003-08-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-02 00:14:07 IP:61.64.xxx.xxx 未訂閱
UDP (User Datagram Protocol) http://www.technik4netzwerk.de/UDP.htm Stefan Heymann Allgemeines Das UDP ist ein paketorientiertes [packet oriented] verbindungsloses [connectionless] unzuverl鱷siges [unreliable] Protokoll der Transport-Schicht (also derselben Schicht wie TCP). Im Gegensatz zu IP k圢nen hier verschiedene UDP-Applikationen 佒er die Port-Nummer unterschieden werden. Port-Nummern Wie bei TCP auch werden bei UDP Port-Nummern verwendet. Die Port-Nummern bis 1024 sind reserviert. Sie werden von der IANA (Internet Assigned Numbers Authority) http://www.iana.org f卣 wichtige Protokolle vergeben. Die Port-Nummern f卣 die g躪gigen Protokolle k圢nen im SERVICES-File eingesehen werden. Die Port-Nummern von 1025 bis 32767 sind frei verf伳bar f卣 eigene Anwendungen. Broadcasts UDP-Pakete ("Datagramme") k圢nen auch per Broadcast an alle Hosts des lokalen Netzes versandt werden (die IP-Adresse des Empf躪gers ist dann 255.255.255.255). Auf diese Weise k圢nen recht einfach Systeme realisiert werden, die bestimmte Listener suchen (die melden sich auf einen solchen Broadcast dann mit einem entsprechenden Paket; alle anderen bekommen das Paket erst gar nicht) oder sich einfach an "alle" wenden. Broadcast-Pakete gehen nur einmal 佒er die Netzwerk-Leitung. Es wird also nicht f卣 jeden Teilnehmer ein getrenntes Paket verschickt. Die Leitungs-Belastung ist also gleich wie beim Versenden eines Pakets an nur einen Peer. Broadcasts m卲sen mit einem speziellen Aufruf erst "freigeschaltet" werden. Programmierung Listener Ein UDP-Listener wird folgenderma惷n aufgebaut: Erzeugung eines Sockets mit der Socket-Funktion des WinSock-API Binden des Socket an den gew刡schten Port Abrufen des n鬣hsten Pakets: Entweder mit RecvFrom, dann blockiert der aktuelle Thread so lange, bis das n鬣hste Paket eingegangen ist Oder mit IoctlSocket immer mal wieder nachsehen ("pollen"), ob Daten in der Eingangs-Queue stehen. Wenn dann RecvFrom aufgerufen wird, kehrt es sofort mit den Daten des n鬣hsten Pakets zur佟k Weitere Methoden: Asynchrone Benachrichtigung (WsaAsyncSelect-Funktion des WinSock-API), Select oder die neuen Overlapped-I/O-Methoden von WinSock 2.0. Inhalt des Pakets entnehmen und interpretieren Ggf. Antwort-Paket senden mit der SendTo-Funktion Erzeugen des Socket (Socket) VAR Sock : TSocket; // Socket-Instanz BEGIN Sock := Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); // SOCK_DGRAM = Datagramm-orienierten Socket erzeugen // IPPROTO_UDP = UDP-Protokoll verwenden IF Sock = INVALID_SOCKET THEN EXIT; Binden des Socket an den Port (Bind) Mit der Bind-Funktion wird ein Socket an den angegebenen Port gebunden, d. h. er kann nun auf diesem Port horchen. VAR SockAddr : TSockAddr_In; // Adress- und Port-Informationen BEGIN FillChar (SockAddr, SizeOf (SockAddr), 0); // Lauter NUL-Bytes SockAddr.sin_family := AF_INET; // Internet-Adressfamilie SockAddr.sin_Port := HtoNs (PortNummer); // Port-Nummer in Network Byte Order SockAddr.sin_Addr.S_Addr := INADDR_ANY; // Empfangen von allen Adressen Bind (Sock, @SockAddr, SizeOf (SockAddr)); Pr伭en, ob Pakete eingegangen sind (IoctlSocket) Diese Funktion pr伭t lediglich, ob sich ein Datagramm in der Eingangs-Queue des Netzwerksystems befindet. Sie kehrt mit ihrem Ergebnis sofort zur佟k. VAR U : U_LONG; begin IoctlSocket (Sock, FIONREAD, @U); IF U > 0 THEN MmoLog.Lines.Add ('Next Datagram is ' IntToStr (U) ' Bytes long') ELSE MmoLog.Lines.Add ('No Datagram waiting at this moment'); Paket empfangen (RecvFrom) Die RecvFrom-Funktion ruft das n鬣hste Datagramm aus der Eingangs-Queue des Netzwerk-Subsystems ab. Sollte sich dort kein Datagramm befinden, wartet ("blockiert") RecvFrom so lange, bis eines eintrifft. VAR Buffer : ARRAY [0..512] OF CHAR; SockAddr : TSockAddr_In; SAL : INTEGER; I : INTEGER; BEGIN FillChar (SockAddr, SizeOf (SockAddr), 0); SAL := SizeOf (SockAddr); I := RecvFrom (Sock, @Buffer, 512, 0, @SockAddr, @SAL); // 512 = Maximale Anzahl zu empfangender Bytes // 0 = Keine OOB-Daten lesen, kein Peek // @SockAddr = Hier werden die Informationen 佒er den Peer abgelegt // SockAddr.sin_Addr = IP-Adresse des Peer // SockAddr.sin_Port = Port-Nummer beim Peer // @SAL = L躪ge der zur佟kgegebenen SockAddr-Struktur // I (RGW) = L躪ge des Pakets in Bytes, wenn positiv IF I = SOCKET_ERROR THEN EXIT; Antwort versenden (SendTo) Mit SendTo werden Datagramme versandt. Da hier auf ein bei RecvFrom eingegangenes Datagramm geantwortet wird, k圢nen die bei RecvFrom eingegangenen Daten "SockAddr" und "SAL" gleich wiederverwendet werden. SendTo (Sock, @Paket, PaketLaenge, 0, @SockAddr, SAL); // @Paket = Zeiger auf zur佟k zu sendenden Byte-Block // PaketLaenge = L躪ge des Byte-Blocks // 0 = Routing erlaubt; kein OOB-Versand // @SockAddr = Von RecvFrom zur佟k erhaltene SockAddr-Struktur // SAL = Von RecvFrom zur佟k erhaltene L躪ge der SockAddr-Struktur Listener schlie惷n (CloseSocket) CloseSocket (Sock); Client Ein Client sendet lediglich Pakete an eine bestimmte IP-Adresse und einen Port. Er kann dann die zur佟kkommenden Pakete wieder empfangen. Eine "Verbindung" wird nicht aufgebaut, da UDP verbindungslos ist. Ablauf: Erzeugen einer Socket-Instanz (Socket) F刜len einer SockAddr-Datenstruktur mit den Angaben f卣 Peer (IP-Adresse) und Port-Nummer Ggf. Broadcasts "freischalten" Versenden des Datenpuffers mit SendTo Ggf. Empfangen der Antwort mit RecvFrom Zerst宁en der Socket-Instanz mit CloseSocket. Ermittlung der IP-Adresse des Peer (Inet_Addr) Umwandlung einer IP-Adresse in Dotted Decimal Notation (z. B. 192.168.1.2) in die 4-Byte-Darstellung vom Typ TIn_Addr. INADDR_BROADCAST ist ein vordefinierter Wert f卣 die Broadcast-Adresse 255.255.255.255. VAR IpV4Addr : TIn_Addr; BEGIN IF DoBroadcast THEN IpV4Addr.S_Addr := INADDR_BROADCAST ELSE IpV4Addr.S_addr := Inet_Addr (PChar (IpAddrStr)); Socket erzeugen (Socket) VAR SAI : TSockAddr_In; SAL : INTEGER; SockAddr : pSockAddr; begin FillChar (SAI, SizeOf (SAI), 0); SAI.sin_family := AF_INET; // Internet-Adress-Familie SAI.sin_port := HtoNs (PortNo); // Port-Nummer SAI.sin_addr := IpV4Addr; // IP-Adresse, wie vorher ermittelt SockAddr := @SAI; Sock := Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); // Socket erzeugen Socket f卣 Broadcast freischalten (SetSockOpt) Hiermit wird die Socket-Option "Broadcast" auf TRUE geschaltet. Erst dann wird die Empf躪ger-Adresse 255.255.255.255 als Broadcast-Adresse interpretiert und nicht als illegale Adresse. Dies ist nur f卣 Broadcasts erforderlich. VAR B : BOOL; BEGIN B := TRUE; SetSockOpt (Sock, SOL_SOCKET, SO_BROADCAST, @B, SizeOf (B)); Daten senden (SendTo) Absenden eines Datagramms mit SendTo. Vor allem bei Broadcasts sollte mit der Option MSG_DONTROUTE daf卣 gesorgt werden, dass das Datagramm nicht in andere Netzwerke geroutet wird. SendTo (Sock, @DataBuf, DataBufLength, MSG_DONTROUTE, SockAddr, SizeOf (SAI)); // @DataBuf = Zeiger auf Daten-Puffer // DataBufLength = Anzahl Bytes im Daten-Puffer // MSG_DONTROUTE = Paket nicht durch Router lassen // SockAddr = SockAddr-Struktur (mit Peer-Adresse und Port-Nummer) // SizeOf (SAI) = L躪ge der SockAddr-Struktur Antwort empfangen (RecvFrom) Analog zum Listener wird hier die Antwort von dem Host empfangen, an den der letzte SendTo ging. Daher kann/muss die dort gef刜lte Datenstruktur SockAddr wiederverwendet werden. VAR DataBuf : ARRAY [0..512] OF CHAR; I : INTEGER; BEGIN SAL := SizeOf (SAI); I := RecvFrom (Sock, @DataBuf, 512, 0, SockAddr, @SAL); IF I > 0 THEN BEGIN // Daten in DataBuf verarbeiten END; END; Socket schlie惷n (CloseSocket) CloseSocket (Sock);
bruce0211
版主


發表:157
回覆:668
積分:279
註冊:2002-06-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-02 08:50:27 IP:211.21.xxx.xxx 未訂閱
長官 這篇的說明內容好像不是英文...
AB
高階會員


發表:166
回覆:262
積分:125
註冊:2003-08-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-12-03 01:02:29 IP:61.64.xxx.xxx 未訂閱
報告 bruce0211 版主 哈哈 下次改進 哈哈
系統時間:2024-05-02 4:49:48
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!