Java socket programming (I)

Source: Internet
Author: User
It is very convenient and powerful to develop network software with Java. This power of Java comes from his unique set of powerful network-related APIs, which are a series of classes and interfaces, the packages are located in java.net and javax.net. In this article, we will introduce the socket concept and illustrate how to use network APIs to manipulate sockets. After this article, you can write low-end network communication software.

  What is socket )?

Network API is typically used to communicate with other programs based on TCP/IP network Java programs. Network API relies on socket for communication. The socket can be seen as an endpoint in the communication connection between two programs. One program writes a piece of information into the socket, and the socket sends this information to another socket, this information can be transmitted to other programs. 1

Let's analyze 1. program a on host a writes a piece of information into the socket, and the content of the socket is accessed by the network management software of host, the information is sent to host B through the network interface card of host a. The network interface card of host B receives the information and sends it to the network management software of host B, the Network Management Software saves this information in the socket of host B, and then program B can read this information in the socket.

Assuming that the third host C is added to the network in Figure 1, how does host a know that the information is correctly transmitted to host B rather than to host C? Each host in a TCP/IP network is assigned a unique IP address. The IP address is a 32-bit unsigned integer. Because it is not converted to binary, it is usually separated by decimal places, such: 198.163.227.6, as you can see, the IP address is composed of four parts, each of which ranges from 0 to 255, to represent an eight-bit address.

It is worth noting that the IP addresses are all 32-bit addresses, which are specified by ipprotocol version 4 (IPv4). At present, because IPv4 addresses are nearly exhausted, IPv6 addresses are gradually replacing IPv4 addresses, the IPv6 address is a 128-bit unsigned integer.

Assuming that the second program is added to host B of the network in Figure 1, how can the information sent from host a be correctly transmitted to program B instead of the newly added program? This is because every TCP/IP-based network communication program is assigned a unique port and port number. The port is an information buffer for retaining the input/output information in the socket, the port number is a 16-bit unsigned integer in the range of 0-65535, to distinguish every program on the host (the port number is like the room number in the House ), for example, the POP3 port number is 256, and each socket is combined into the IP address, port, and port number, in this way, we can differentiate every socket T. Next we will talk about two sockets: stream socket and self-addressing data socket.

  Stream socket)

At any time, a reliable connection is required for sending and receiving information between two network applications, and the stream socket relies on the TCP protocol to ensure that the information reaches the destination correctly. In fact, an IP packet may be lost in the network or an error occurs during transmission. In any case, the TCP of the receiver will contact the sender TCP to resend the IP packet. This is called establishing a reliable connection between two stream sockets.

Stream socket plays a necessary role in the C/S program, the client program (network applications that need to access certain services) create a stream socket object that acts as the IP address of the host and the port number of the server program (network application that provides services for client applications.

The initialization code of the client stream socket transmits the IP address and port number to the network management software of the client host, and the management software transmits the IP address and port number to the server host through Nic; the server host reads the data transmitted by the NIC, and then checks whether the server program is listening. This kind of listening is still performed through the socket and port. If the server program is listening, the network management software on the server sends a positive response signal to the client network management software. After receiving the response signal, the client stream socket initialization Code creates a port number for the client program, and pass the port number to the socket of the server program (the server program will use this port number to identify whether the incoming information belongs to the Client Program) and complete the initialization of the stream socket.

If the server program is not listening, the network management software on the server sends a negative signal to the client, the stream socket initialization code of the client program throws an exception object without establishing communication connections or creating a stream socket object. This is like making a phone call. When someone establishes a communication, the phone will be suspended.

This part of work includes three associated classes: inetaddress, socket, and serversocket. The inetaddress object depicts 32-bit or 128-bit IP addresses. The socket object represents the client program stream socket, and the serversocket represents the service program stream socket. All three classes are located in the java.net package.

  Inetaddress class

The inetaddress class plays an important role in Network API socket programming. Parameters are passed to the stream socket class and self-addressing socket class constructor or non-constructor method. Inetaddress describes 32-bit or 64-bit IP addresses. To complete this function, the inetaddress class mainly relies on two support classes: inet4address and inet6address. These three classes are inheritance relationships and inetaddrress is the parent class, inet4address and inet6address are subclasses.

Because the inetaddress class has only one constructor and cannot pass parameters, you cannot directly create an inetaddress object. For example, the following method is incorrect:

Inetaddress IA = new inetaddress ();

However, we can create an inetaddress object or an inetaddress array using the following five factory methods:

. The getallbyname (string host) method returns a reference to an inetaddress object. Each object contains a separate IP address indicating the corresponding host name, which is passed through the host parameter, if no IP address exists for the specified host, this method will throw an unknownhostexception object.

. The getbyaddress (byte [] ADDR) method returns a reference to an inetaddress object, which contains an IPv4 address or IPv6 address. The IPv4 address is a 4-byte array, the IPv6 address is a 16-byte address array. If the returned array is neither 4-byte nor 16-byte, the method will throw an unknownhostexception object.

. The getbyaddress (string host, byte [] ADDR) method returns a reference to an inetaddress object, which contains an IP address specified by the host and a 4-byte ADDR array, or the IP address specified by the host and 16-byte ADDR arrays. If the array is neither 4-byte nor 16-byte, this method will throw an unknownhostexception object.

. The getbyname (string host) method returns an inetaddress object, which contains an IP address corresponding to the host specified by the host parameter. If no IP address exists for the specified host, the method throws an unknownhostexception object.

. The getlocalhost () method returns an inetaddress object, which contains the IP address of the Local Machine. Considering that the local host is both a client host and a server host, to avoid confusion, we call a client host and a server host.

The methods mentioned above all mention returning one or more references to the inetaddress object. In fact, each method returns a reference to one or more inet4address/inet6address objects, the caller does not need to know the referenced subtype. On the contrary, the caller can use the returned reference to call the non-static method of the inetaddress object, including the subtype polymorphism to ensure that the overloaded method is called.

The inetaddress and its child-type object process the conversion from the host name to the IPv4 or IPv6 address of the host. To complete this conversion, you need to use the domain name system. The following Code demonstrates how to call getbyname (string host) method to obtain the inetaddress subclass object. This object contains the IP address corresponding to the host parameter:

Inetaddress IA = inetaddress. getbyname ("www.javajeff.com "));

Once the inetaddress subclass object is referenced, you can call various inetaddress methods to obtain the IP address information in the inetaddress subclass object. For example, you can call getcanonicalhostname () get the standard host name from the Domain Name Service; gethostaddress () Get the IP address; gethostname () Get the host name; isloopbackaddress () judge whether the IP address is a loopback address.

List1 is a Demo code: inetaddressdemo

// Inetaddressdemo. Java

Import java.net .*;

Class inetaddressdemo
{
Public static void main (string [] ARGs) throws unknownhostexception
{
String host = "localhost ";

If (ARGs. Length = 1)
Host = ARGs [0];

Inetaddress IA = inetaddress. getbyname (host );

System. Out. println ("canonical host name =" +
IA. getcanonicalhostname ());
System. Out. println ("host address =" +
IA. gethostaddress ());
System. Out. println ("host name =" +
IA. gethostname ());
System. Out. println ("is loopback address =" +
IA. isloopbackaddress ());
}
}

When there is no command line parameter, the code output is similar to the following result:

Canonical host name = localhost
Host address = 127.0.0.1
Host Name = localhost
Is loopback address = true

Inetaddressdemo gives you a selection of the specified host name as a command line parameter. If no host name is specified, localhost (client) is used. inetaddressdemo calls getbyname (string host) method to obtain the reference of an inetaddress subclass object. The reference obtains the output of the standard Host Name, host address, host name, and whether the IP address is a loopback address.

Socket

When the client program needs to communicate with the server program, the client program creates a socket object on the client. The socket class has several constructors. Two common constructor functions are socket (inetaddress ADDR, int port) and socket (string host, int port ), both constructors create a socket-based stream socket that connects to the server-side stream socket. For the first inetaddress subclass object, use the ADDR parameter to obtain the IP address of the server host. For the second function, the host parameter is allocated to the inetaddress object. If no IP address is consistent with the host parameter, then the unknownhostexception object will be thrown. Both functions obtain the server port number through the port parameter. If a connection has been established, the Network API binds the IP address and any port number of the client program in the socket-based stream socket of the client. Otherwise, both functions will throw an ioexception object.

If a socket object is created, it may call the getinputstream () method of socket to obtain the information sent from the input stream from the service program, or call the getoutputstream () method of socket () method to obtain the output stream to send messages. After the reading and writing activity is complete, the client program calls the close () method to close the stream and stream socket. The following Code creates a socket object with the host address of the service program as 198.163.227.6 and port number as 13, then, read the input stream from the newly created socket object, and then close the stream and socket object.

Socket S = new socket ("198.163.227.6", 13 );
Inputstream is = S. getinputstream ();
// Read from the stream.
Is. Close ();
S. Close ();

Next, we will demonstrate a customer program of a stream socket. This program will create a socket object and the socket will access the service program running on the specified host port 10000, if the access is successful, the client program will send a series of commands to the service program and print the response of the service program. List2 let us create the program ssclient source code:

Listing 2: ssclient. Java

// Ssclient. Java

Import java. Io .*;
Import java.net .*;

Class ssclient
{
Public static void main (string [] ARGs)
{
String host = "localhost ";

// If User specifies a command-line argument, that argument
// Represents the host name.

If (ARGs. Length = 1)
Host = ARGs [0];

Bufferedreader BR = NULL;
Printwriter PW = NULL;
Socket S = NULL;

Try
{
// Create a socket that attempts to connect to the server
// Program on the host at port 10000.

S = new socket (host, 10000 );

// Create an input stream reader that chains to the socket's
// Byte-oriented input stream. The input stream Reader
// Converts bytes read from the socket to characters.
// Conversion is based on the platform's default character
// Set.

Inputstreamreader ISR;
ISR = new inputstreamreader (S. getinputstream ());

// Create a buffered reader that chains to the input stream
// Reader. The buffered reader supplies a convenient method
// For reading entire lines of text.

BR = new bufferedreader (ISR );

// Create a print writer that chains to the socket's byte-
// Oriented output stream. The print writer creates
// Intermediate output stream writer that converts
// Characters sent to the socket to bytes. The conversion
// Is based on the platform's default character set.

PW = new printwriter (S. getoutputstream (), true );

// Send the date command to the server.

PW. println ("date ");

// Obtain and print the current date/time.

System. Out. println (Br. Readline ());
// Send the pause command to the server. This allows several
// Clients to start and verifies that the server is spawning
// Multiple threads.

PW. println ("pause ");
// Send the Dow command to the server.

PW. println ("Dow ");

// Obtain and print the current day of week.

System. Out. println (Br. Readline ());

// Send the DOM command to the server.
 
PW. println ("dom ");

// Obtain and print the current day of month.

System. Out. println (Br. Readline ());

// Send the doy command to the server.

PW. println ("doy ");

// Obtain and print the current day of year.

System. Out. println (Br. Readline ());
}
Catch (ioexception E)
{
System. Out. println (E. tostring ());
}
Finally
{
Try
{
If (BR! = NULL)
BR. Close ();

If (PW! = NULL)
PW. Close ();

If (s! = NULL)
S. Close ();
}
Catch (ioexception E)
{
}
}
}
}

Run this program and you will get the following results:

Tue Jan 29 18:11:51 CST 2002
Tuesday
29
29

Ssclient creates a socket object to contact the service program running on port 10000 of the host. the IP address of the host is determined by the host variable. Ssclient will obtain the input and output streams of the socket. It is very easy to read and write the strings around the input stream of bufferedreader and the output stream of printwriter, the ssclient service programs issue various date/time commands and get a response. Each response is printed. Once the last response is printed, the finally substring of the try/catch/Finally structure will be executed, finally substrings will disable bufferedreader and printwriter before closing the socket.

After ssclient source code is compiled, you can enter Java ssclient to execute this program. If appropriate programs run on different hosts, the host name/IP address is used as the parameter input, for example, if www.sina.com.cn is the host that runs the server program, the input method is Java ssclient www.sina.com.cn.

  Tips

The socket class contains many useful methods. For example, getlocaladdress () will return a reference to the inetaddress subclass object containing the client program IP address; getlocalport () will return the client program port number; getinetaddress () A reference to the inetaddress subclass object containing the Server IP address will be returned; getport () will return the port number of the service program.

Serversocket class

Because ssclient uses a stream socket, the service program must also use a stream socket. This requires creating a serversocket object. serversocket has several constructor functions. The simplest is serversocket (INT port). When serversocket (INT port) is used to create a serversocket object, the port parameter transmits the port number, this port is the port on which the server listens for connection requests. If an error occurs at this time, an ioexception object will be thrown. Otherwise, a serversocket object will be created and ready to receive connection requests.

Next, the service program enters an infinite loop. The infinite loop starts from the call of the serversocket accept () method. After the call starts, the accept () method will cause the call thread to block until the connection is established. After the connection is established, accept () returns a newly created socket object bound to the IP address or port number of the client program.

Because a single service program may communicate with Multiple customer programs, it cannot take much time for the service program to respond to the customer program, otherwise, the customer program may spend a lot of time waiting for the establishment of communication before obtaining the service. However, the session between the service program and the customer program may be long (similar to the phone number ), therefore, to speed up the response to the client program connection request, a typical method is to run a background thread on the server host, which processes the communication between the service program and the client program.

To demonstrate the concepts we mentioned above and complete the ssclient program, we will create an ssserver program. The program will create a serversocket object to listen to connection requests on port 10000, if the connection is successful, the service program waits for the connection input, starts a thread to process the connection, and responds to commands from the client program. The code for this program is as follows:

Listing 3: ssserver. Java

// Ssserver. Java

Import java. Io .*;
Import java.net .*;
Import java. util .*;

Class ssserver
{
Public static void main (string [] ARGs) throws ioexception
{
System. Out. println ("server starting.../N ");

// Create a server socket that listens for incoming connection
// Requests on port 10000.

Serversocket Server = new serversocket (10000 );

While (true)
{
// Listen for incoming connection requests from client
// Programs, establish a connection, and return a socket
// Object that represents this connection.

Socket S = server. Accept ();

System. Out. println ("accepting connection.../N ");

// Start a thread to handle the connection.

New serverthread (s). Start ();
}
}
}

Class serverthread extends thread
{
Private socket S;

Serverthread (socket S)
{
This. S = s;
}

Public void run ()
{
Bufferedreader BR = NULL;
Printwriter PW = NULL;

Try
{
// Create an input stream reader that chains to the socket's
// Byte-oriented input stream. The input stream Reader
// Converts bytes read from the socket to characters.
// Conversion is based on the platform's default character
// Set.

Inputstreamreader ISR;
ISR = new inputstreamreader (S. getinputstream ());

// Create a buffered reader that chains to the input stream
// Reader. The buffered reader supplies a convenient method
// For reading entire lines of text.

BR = new bufferedreader (ISR );

// Create a print writer that chains to the socket's byte-
// Oriented output stream. The print writer creates
// Intermediate output stream writer that converts
// Characters sent to the socket to bytes. The conversion
// Is based on the platform's default character set.

PW = new printwriter (S. getoutputstream (), true );

// Create a calendar that makes it possible to obtain date
// And time information.

Calendar c = calendar. getinstance ();

// Because the client program may send multiple commands,
// Loop is required. keep looping until the client either
// Explicitly requests termination by sending a command
// Beginning with letters bye or implicitly requests
// Termination by closing its output stream.

Do
{
// Obtain the client program's next command.

String cmd = Br. Readline ();

// Exit if client program has closed its output stream.

If (cmd = NULL)
Break;
  
// Convert command to uppercase, for example, of comparison.

Cmd = cmd. touppercase ();

// If client program sends bye command, terminate.

If (CMD. startswith ("bye "))
Break;

// If client program sends date or time command, return
// Current date/time to the client program.

If (CMD. startswith ("date") | cmd. startswith ("time "))
PW. println (C. gettime (). tostring ());

// If client program sends dom (Day of month) command,
// Return current day of month to the client program.

If (CMD. startswith ("dom "))
PW. println ("" + C. Get (calendar. day_of_month ));

// If client program sends Dow (day of week) command,
// Return Current weekday (as a string) to the client
// Program.

If (CMD. startswith ("Dow "))
Switch (C. Get (calendar. day_of_week ))
{
Case calendar. Sunday: pw. println ("Sunday ");
Break;

Case calendar. Monday: pw. println ("Monday ");
Break;

Case calendar. Tuesday: pw. println ("Tuesday ");
Break;

Case calendar. Wednesday: pw. println ("Wednesday ");
Break;

Case calendar. Thursday: pw. println ("Thursday ");
Break;

Case calendar. Friday: pw. println ("Friday ");
Break;

Case calendar. Saturday: pw. println ("Saturday ");
}

// If client program sends doy (Day of year) command,
// Return current day of year to the client program.

If (CMD. startswith ("doy "))
PW. println ("" + C. Get (calendar. day_of_year ));

// If client program sends pause command, sleep for three
// Seconds.
 
If (CMD. startswith ("pause "))
Try
{
Thread. Sleep (3000 );
}
Catch (interruptedexception E)
{
}
}
While (true );
{
Catch (ioexception E)
{
System. Out. println (E. tostring ());
}
Finally
{
System. Out. println ("Closing connection.../N ");

Try
{
If (BR! = NULL)
BR. Close ();

If (PW! = NULL)
PW. Close ();

If (s! = NULL)
S. Close ();
}
Catch (ioexception E)
{
}
}
}
}

Run this program to get the following output:

Server starting...
Accepting connection...
Closing connection...

The source code of ssserver declares a pair of classes: ssserver and serverthread; the main () method of ssserver creates a serversocket object to listen to connection requests on port 10000. If yes, the ssserver enters an infinite loop and calls the serversocket accept () method to wait for the connection request, and starts the background thread to process the request returned by the connection (accept ). The thread starts from the start () method inherited by serverthread and runs the code in the run () method of serverthread.

Once the run () method runs, the thread creates bufferedreader, printwriter, and calendar objects and enters a loop, which is read by the read (through the Read line () of bufferedreader ()) A line of text from the client program starts. The text (command) is stored in the string object referenced by CMD. What happens if the client program closes the output stream too early? The answer is: cmd will not be assigned a value.

Note that this situation must be taken into account: when the service program is reading the input stream, the client program closes the output stream. If this situation is not processed, the program will generate an exception.

Once the source code of ssserver is compiled, you can enter Java ssserver to run the program. After running ssserver, you can run one or more ssclient programs.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.