<?xml version="1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Sockets and DNS - ClanLib SDK</title> <link rel="stylesheet" media="screen" type="text/css" href="clanlib.css"/> <link rel="icon" href="gfx/favicon.png" type="image/png"/> </head> <body> <div id="content"> <h1><a href="."><img src="gfx/clanlib.png" alt="ClanLib SDK" /></a></h1> <h2> <img src="gfx/overview.png"/>Sockets and DNS </h2> <p>The clanNetwork library provides three simple classes for basic TCP and UDP communication over the Internet:</p> <ul> <li><span class="code">CL_TCPListen</span></li> <li><span class="code">CL_TCPConnection</span></li> <li><span class="code">CL_UDPSocket</span></li> <li><span class="code">CL_SocketName</span></li> </ul> <h3>Internet Protocol Basics</h3> <p>Although you can find much better information elsewhere on how the Internet works and how IP packet routing operates, we will give a small summary here of its operation from the point of an application.</p> </p>Typically applications communicate over the Internet or on a Local Area Network (LAN) using either the Transmission Control Protocol (TCP) or the User Datagram Protocol (UDP). The TCP protocol is used for connection based communication between two parties (like a phone call), while the UDP protocol is used to send individual messages without an actual connection (like sending a SMS).</p> <p>With both protocols you connect or send messages to a specific <i>IP address</i>. But because there may be many different programs running on a machine, the destination is also identified by a <i>port</i>. The combination of both is called a <i>socket name</i> and is represented by the class <span class="code">CL_SocketName</span> in clanNetwork. For example, the Google search engine web server runs on the server www.google.com, port 80 (the http protocol port).</p> <p>The <span class="code">CL_SocketName</span> class in clanNetwork is designed so it can either hold a machine DNS name or an IP address of the server. This is because finding the DNS name for an IP address (or visa versa) may take time and therefore is only done when absolutely neccessary. However, it is easy enough to convert from one type to the other:</p> <pre> CL_SocketName dnsname("www.google.com", "80"); CL_String ipaddress = dnsname.lookup_ipv4(); CL_SocketName ipname(ipaddress, "80"); CL_String dnsname = ipname.lookup_hostname(); </pre> <p>Just remember that these two functions may block for a while when contacting the DNS server, so use them wisely.</p> <h3>TCP Communication</h3> <p>Connecting to an existing server using TCP is fairly simple. If we want to fetch the HTML page for www.google.com, we might do this:</p> <pre> CL_SocketName google_server("www.google.com", "80"); CL_TCPConnection connection(google_server); CL_String8 http_request = "GET / HTTP/1.1\r\n" "Host: www.google.com\r\n" "Connection: close\r\n" "\r\n"; connection.write(http_request.data(), http_request.length()); while(true) { char buffer[16*1024]; int received = connection.read(buffer, 16*1024-1, false); if (received == 0) break; buffer[received] = 0; CL_Console::write(buffer); } connection.disconnect_graceful(); </pre> <p>To create your own server that allow clients to connect to a port, you use the <span class="code">CL_TCPListen</span> class:</p> <pre> CL_SocketName listen_port("5555"); CL_TCPListen listen(listen_port); // Wait 60 seconds for someone to connect: bool someone_connected = listen.get_accept_handle().wait(60*1000); if (someone_connected) { CL_TCPConnection connection = listen.accept(); CL_SocketName remote_name = connection.get_remote_name(); CL_Console::write_line("%1 connected", remote_name.get_address()); CL_String8 messsage = "Hello There!"; connection.write(message.data(), message.length()); connection.disconnect_graceful(); } else { CL_Console::write_line("Nobody connected for 60 seconds"); } </pre> <h3>UDP Communication</h3> <p>Talking via UDP is slightly different because there is no connection. Instead, you communicate by sending single message packets to an IP address and port:</p> <pre> CL_SocketName our_port("5555"); CL_SocketName destination("example.net", "5678"); CL_UDPSocket udp; udp.bind(our_port); udp.send(message.data(), message.length(), destination); </pre> <p>If the UDP socket is not bound to a port, a random available port will be chosen when the first message is sent. The <span class="code">bind()</span> command is therefore only needed for servers.</p> <p>Because UDP communication is connectionless, anyone can send messages to our socket and we retrieve the messages like this:</p> <pre> // Wait 60 seconds for a message: bool data_available = udp.get_read_event().wait(60*1000); if (data_available) { char buffer[16*1024]; CL_SocketName sender_name; int received = udp.receive(buffer, 16*1024, sender_name); CL_Console::write_line("%1 sent us %2 bytes of data!", sender_name.get_address(), received); } </pre> </div> </body> </html>