1. Perl
  2. socket

Communicate with socket

A description of Perl's "sockets".

What is a socket?

Sockets are used when you want to exchange data over a network . For example, a web server exchanges data with a browser over the network. At this time, the socket is used in the internal mounting.

The Perl module has a module called LWP::UserAgent to get the page of the website. If you look at the lowest level part of this implementation, sockets are used.

If you want to create an application that wants to exchange data over the network, use sockets or use wrapper classes that make sockets easy to use.

Socket image

It's easiest to think of a socket as a kind of filehandle . To open a file in write mode

my $fh;
my $file = 'somefile';
open($fh, ">", $file)

To do. When opened like this

print $fh'aaa';

You can write to a file using the print function. The case for sockets is very similar. If you create a socket and write to it, computers over the network can read it.

For the sake of simplicity, I will omit the details, but to open the socket and write, write as follows.

my $sock;
socket ($sock, argument omitted);

print $sock'aaa';

The socket function corresponds to the open function. When writing, you can write with the print function.

Studying sockets is difficult

Studying sockets is difficult. There are several difficult causes.

The procedure for creating a socket is complicated

The procedure for creating a socket is complicated. You need to write the source code over and over again before you can memorize and use the socket.

Two programs, client and server, are required to communicate

The hard part about studying sockets is that you have to write two programs, client and server . Even if you create only a client, you cannot try the program without a communication partner. Due to these difficulties, we will first prepare the server-side program here so that we can concentrate on creating the client-side program at first.

The status of the communication partner is uncertain

Since it communicates over the network, the status of the other party is uncertain . There is no guarantee that it will almost certainly be written locally like a file. There may be sudden disconnections or delays. It means that you need to write a program to handle such errors.

The simplest example of

sockets. Echo server

Here is an example socket program that you can run first. When the client sends the character Hello, the server adds the echo: string to the string and returns it to the client.

This example is not complete, but it is the basis for learning client-server communication. It's one of the simplest client-server programs, but it's quite difficult for a normal program. First look at the example in action.

Client - side program echo_client.pl

A program that sends a string to the server and outputs the received string.

use strict;
use warnings;
use Socket;

# Client
# 1. Creating a socket
my $sock;
socket ($sock, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
  or die "Cannot create socket:$!";

# 2. Creating socket information

# Host name to connect to
my $remote_host = 'localhost';
my $packed_remote_host = inet_aton ($remote_host)
  or die "Cannot pack $remote_host:$!";

# Port number to connect to
my $remote_port = 9000;

# Pack the host name and port number
my $sock_addr = sockaddr_in ($remote_port, $packed_remote_host)
  or die "Cannot pack $remote_host: $remote_port:$!";

# 3. Connect using socket
connect ($sock, $sock_addr)
  or die "Cannot connect $remote_host: $remote_port:$!";

# 4. Writing data
# Do not write buffer.
my $old_handle = select $sock;
$| = 1;
select $old_handle;

print $sock "Hello";

# Finish writing
shutdown $sock, 1;

# 5. Read data
while (my $line = <$sock>) {
  print $line;
}

# 6. Close the socket
close $sock;

2. Server - side program echo_server.pl

This is a server-side program. Adds the string echo: to the string received from the client and returns it to the client. while statement is used to create a state that can be accepted repeatedly.

use strict;
use warnings;
use Socket;

# Server

# 1. Creating a reception socket

my $sock_receive;
socket ($sock_receive, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
  or die "Cannot create socket:$!";

# 2. Creating reception socket information
my $local_port = 9000;

my $pack_addr = sockaddr_in ($local_port, INADDR_ANY);

# 3. Link reception socket and reception socket information
bind ($sock_receive, $pack_addr)
  or die "Cannot bind:$!";

# 4. Get ready to accept connections.
listen ($sock_receive, SOMAXCONN)
  or die "Cannot listen:$!";

# 5. Accept and respond to the connection.
my $sock_client; # Socket for communication with client

while (accept ($sock_client, $sock_receive)) {
  my $content;
  
  # Reading data from the client
  while (my $line = <$sock_client>) {
    $content. = $line;
  }
  
  # Write data to client
  print $sock_client "echo: $content";
  close $sock_client;
}

3. Run the example

To run this example, first

perl echo_server.pl

Start the server as. The server listens for requests from clients.

Next, launch another terminal to execute the client-side program. and,

perl echo_client.pl

will do. Then, a response is returned from the echo server,

echo: Hello

It will be displayed.

Create a socket

This is an explanation of the part of creating a socket on the client side.

use Socket;

# 1. Creating a socket
my $sock;
socket ($sock, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
  or die "Cannot create socket:$!";

1. Creating a socket

To use socket-related functions and constants

use Socket;

will do. Use the socket function to create a socket.

my $sock;
socket ($sock, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))

The socket function takes four arguments. The first argument specifies the socket you want to read or write. If the socket function succeeds by passing $sock declared in my $sock; as the first argument, data can be read and written over the network through $sock.

Specify the domain in the second argument. In the third argument, specify the type. Specify the protocol number in the 4th argument.

2. Specifying the domain

The second argument of the socket function specifies the domain . It's very confusing, but it has nothing to do with domain names, which are used in a similar sense to host names. As for the feeling of words, it may be better to imagine the word area , which is a translation of the domain into Japanese. Commonly used domains include PF_UNIX domains and PF_INET domains .

domain

Range
PF_UNIX local
PF_INET the Internet

The PF_UNIX domain represents an area of one local computer . This means that the scope of communication is only within the local computer.

The PF_INET domain represents the area covered by the Internet . This means that computers around the world are within range of communication.

Since this example is trying to communicate via the Internet, PF_INET is specified as the domain. By the way, the acronym PF is an abbreviation for the word protocol family.

3. Type specification

Specify type for the third argument of the socket function. If you want to communicate using TCP , specify SOCK_STREAM . If you want to communicate using UDP , specify SOCK_DGRAM .

type Communication method
SOCK_STREAM TCP
SOCK_DGRAM UDP

TPC is a reliable communication method. After confirming the connection with the other party, start exchanging data. In addition, even if data is lost on the network, it is a communication method that resends and reliably delivers the data. Many applications use TCP to communicate.

UPD is a unreliable but fast communication method. Send data without checking the connection with the other party. Also, even if data is lost on the network, it will not be resent. Use UDP when some data such as audio and video is lost but it is meaningful enough and speed is prioritized.

When communicating a string, it is necessary to communicate using TCP because the data becomes meaningless if a part is lost.

4. Specifying the protocol number

Specify protocol number in the 4th argument of the socket function.

socket ($sock, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))

The protocol is not the application layer protocol such as HTTP or FTP, but the transport layer protocol such as TCP or UDP is specified by number .

To get the protocol number from the protocol name, use the getprotobyname function. Obtain the protocol number from the protocol name by referring to the file that shows the correspondence between the protocol name and the protocol number that exist in the OS. Specify the protocol name in lowercase.

In the case of Windows, the file showing the correspondence between the protocol name and the protocol number

C:\WINDOWS\system32\drivers\etc\protocol

It is in. For Unix-like OS

/ etc/protocols

I think it is in. (Confirmed with Fedora 7)

The contents of these files are

# <protocol name> <assigned number> [aliases ...][# <comment>]
# ip 0 IP Internet protocol
# icmp 1 ICMP Internet control message protocol
# ggp 3 GGP Gateway-gateway protocol
# tcp 6 TCP Transmission control protocol
# egp 8 EGP Exterior gateway protocol
# pup 12 PUP PARC universal packet protocol
# udp 17 UDP User datagram protocol
# hmp 20 HMP Host monitoring protocol
# xns-idp 22 XNS-IDP Xerox NS IDP
# rdp 27 RDP "reliable datagram" protocol
# rvd 66 RVD MIT remote virtual disk

It looks like this.

5. Error handling

It is safer to handle the error.

socket ($sock, PF_INET, SOCK_STREAM, getprotobyname ('tcp'))
  or die "Cannot create socket:$!";

If the socket function fails, it returns undef and sets $! To the error content.

6. Tips for learning sockets

It takes a lot of effort to be able to use sockets. It turns out that there are many things you need to understand just by looking at creating sockets. The trick to remembering sockets is to type them many times. I can't remember just by looking at it.

Create information on the connection destination of the socket

Explains how to create information on the connection destination of the socket. The following part of the echo server example client-side program.

# 2. Creating socket information

# Host name to connect to
my $remote_host = 'localhost';
my $packed_remote_host = inet_aton ($remote_host)
  or die "Cannot pack $remote_host:$!";

# Port number to connect to
my $remote_port = 9000;

# Pack the host name and port number
my $sock_addr = sockaddr_in ($remote_port, $packed_remote_host)
  or die "Cannot pack $remote_host: $remote_port:$!";

I use a socket to connect to a server, but at that time I need information on the server to connect to .

1. Host name or IP address of the connection destination

The first thing you need is the hostname or IP address to connect to. The Internet uses IP addresses to uniquely identify your computer. It also generally has a corresponding host name. Either the host name or the IP address can be used.

# Host name to connect to
my $remote_host = 'localhost';

or

my $remote_host = '127.0.0.1';

127.0.0.1 is called loopback address , and localhost is the host name that corresponds to the loopback address. A loopback address is a virtual address that points to itself.

Using the loopback address has the effect of communicating with yourself over the network. I do this because I want to test the server and client in a local environment.

When actually communicating over the Internet, specify the IP address or host name of the server computer.

2. Convert the host name of the string to binary format

The host name or IP address cannot be used as a string . You need to convert it to binary format using the inet_aton function.

If the string given to inet_aton is a host name, it will be converted to the corresponding IP address and then to the binary format that represents the IP address.

my $packed_remote_host = inet_aton ($remote_host)
  or die "Cannot pack $remote_host:$!";

In aton, a means ascii and n means network. To be precise, the binary format is a 4-byte number expressed in network byte order .

3. Port number

IP addresses and host names uniquely identify a computer, while port numbers are used to identify applications running within that computer.

# Port number to connect to
my $remote_port = 9000;

Port numbers can be used from 0 to 65535. However, 0 to 1023 are common port numbers, so use 1024 to 65535. Make sure to use the same port number to communicate with the client and server.

4. Collect port numbers and IP addresses

Next, you need to group the port number and IP address together using the sockaddr_in function.

# Pack the host name and port number
my $sock_addr = sockaddr_in ($remote_port, $packed_remote_host)
  or die "Cannot pack $remote_host: $remote_port:$!";

The first argument is the port number, and the second argument is the IP address converted to binary format. The $sock_addr created in this way will be passed to the argument of the connect function for connection.

Connect to server - connect function

Use the connect function to connect to the server.

# 3. Connect using socket
connect ($sock, $sock_addr)
  or die "Cannot connect $remote_host: $remote_port:$!";

Connect to the server

Use the connect function to connect to the server. The first argument is the socket created by the socket function.

The second argument is "s"

Information on the port number and IP address of the connection destination created by the "ockaddr_in" function].

If you call the connect function with these two arguments, $sock becomes a read/write socket . You can use $sock to exchange data with the server.

Related Informatrion