3.1 连接到服务器
import java.io.*;
import java.net.*;
import java.util.*;
/**
* This program makes a socket connection to the atomic clock in
* Boulder,Colorado, and prints the time that the server sends.
*
*/
public class SocketTest {
public static void main(String[] args) {
try {
// 连接到设在美国科罗拉多州博尔德市的国家标准与技术研究所,它负责提供铯原子钟的计量时间
Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13);
try {
InputStream inStream = s.getInputStream();
Scanner in = new Scanner(inStream);
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println(line);
}
} finally {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.2 实现服务器
import java.io.*;
import java.net.*;
import java.util.Scanner;
/**
* This program implements a simple server that listens to port 8189 and echoes
* back all client input
*
*/
public class EchoServer {
public static void main(String[] args) {
try {
// establish server socket
ServerSocket s = new ServerSocket(8189);
// wait for client connection
Socket incoming = s.accept();
try {
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true/* autoFlush */);
out.println("Hello!Enter BYE to exit.");
// echo client input
boolean done = false;
while (!done && in.hasNext()) {
String line = in.nextLine();
out.println("Echo:" + line);
if (line.trim().equals("BYE"))
done = true;
}
} finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
通常,服务器总是不间断地运行在服务器计算机上,来自整个因特网的用户希望同时使用服务器。拒绝多客户端连接将使得一个用户因长时间地连接服务而独占服务。针对这一情况,我们可以采用这样的办法:每当程序建立一个新的套接字连接,程序创建一个新的线程来处理服务器和该客户之间的连接。主程序将立即返回并等待下一个连接。
为多个客户服务
import java.net.*;
import java.io.*;
import java.util.*;
/**
* This program implements a multithreaded server that listens to port 8189 and
* echoed back all client input.
*
*/
public class ThreadedEchoServer {
public static void main(String[] args) {
try {
int i = 1;
ServerSocket s = new ServerSocket(8189);
while (true) {
Socket incoming = s.accept();
System.out.println("Spawning" + i);
Runnable r = new ThreadedEchoHandler(incoming, i);
Thread t = new Thread(r);
t.start();
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* This class handles the client input for one server socket connection.
*
*/
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private int counter;
public ThreadedEchoHandler(Socket i, int c) {
this.incoming = i;
this.counter = c;
}
public void run() {
try {
try {
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true/* autoFlush */);
out.println("Hello!Enter BYE to exit.");
boolean done = false;
while (!done && in.hasNext()) {
String line = in.nextLine();
out.println("Echo to " + counter + "th client:" + line);
if (line.trim().equals("BYE"))
done = true;
}
} finally {
incoming.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.3 发送E-MAIL
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
public class MailTest {
public static void main(String[] args) {
JFrame frame = new MailTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class MailTestFrame extends JFrame {
public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 300;
private Scanner in;
private PrintWriter out;
private JTextField from;
private JTextField to;
private JTextField smtpServer;
private JTextArea message;
private JTextArea comm;
public MailTestFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setTitle("MailTest");
setLayout(new GridBagLayout());
add(new JLabel("From:"), new GBC(0, 0).setFill(GBC.HORIZONTAL));
from = new JTextField(20);
add(from, new GBC(1, 0).setFill(GBC.HORIZONTAL).setWeight(100, 0));
add(new JLabel("To:"), new GBC(0, 1).setFill(GBC.HORIZONTAL));
to = new JTextField(20);
add(to, new GBC(1, 1).setFill(GBC.HORIZONTAL).setWeight(100, 0));
add(new JLabel("SMTP server:"), new GBC(0, 2).setFill(GBC.HORIZONTAL));
smtpServer = new JTextField(20);
// 这里发现一个问题,如果下面误写为add(from,……),那么运行出现的界面中没有出现from对应的文本域元素
add(smtpServer, new GBC(1, 2).setFill(GBC.HORIZONTAL).setWeight(100, 0));
message = new JTextArea();
add(new JScrollPane(message), new GBC(0, 3, 2, 1).setFill(GBC.BOTH)
.setWeight(100, 100));
comm = new JTextArea();
add(new JScrollPane(comm), new GBC(0, 4, 2, 1).setFill(GBC.BOTH)
.setWeight(100, 100));
JPanel buttonPanel = new JPanel();
add(buttonPanel, new GBC(0, 5, 2, 1));
JButton sendButton = new JButton("send");
buttonPanel.add(sendButton);
sendButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
new Thread(new Runnable() {
public void run() {
comm.setText("");
sendMail();
}
}).start();
}
});
}
public void sendMail() {
Socket s;
try {
s = new Socket(smtpServer.getText(), 25);
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
in = new Scanner(inStream);
out = new PrintWriter(outStream, true/* autoFlush */);
String hostName = InetAddress.getLocalHost().getHostName();
receive();
send("HELO " + hostName);
receive();
send("AUTH LOGIN");
receive();
send("aHhsMD?yMA==");//用户名经Base64编码后的数据
send("aHV4aWFvbGU?ODIx?jg0MQ==");//密码经Base64编码后的数据
receive();
send("MAIL FROM: <" + from.getText() + ">");
receive();
send("RCPT TO: <" + to.getText() + ">");
receive();
send("DATA");
receive();
send(message.getText());
send(".");
receive();
s.close();
} catch (UnknownHostException e) {
comm.append("Error:" + e);
} catch (IOException e) {
comm.append("Error:" + e);
}
}
public void send(String s) throws IOException {
comm.append(s);
comm.append("\n");
out.print(s.replaceAll("\n", "\r\n"));
out.print("\r\n");
out.flush();
}
public void receive() throws IOException {
if (in.hasNextLine()) {
String line = in.nextLine();
comm.append(line);
comm.append("\n");
}
}
}
/**
* This class simplifies the use of the GridBagConstraints class.
*/
class GBC extends GridBagConstraints {
/**
* Constructs a GBC with a given gridx and gridy position and all other grid
* bag constraint values set to the default.
*
* @param gridx
* the gridx position
* @param gridy
* the gridy position
*/
public GBC(int gridx, int gridy) {
this.gridx = gridx;
this.gridy = gridy;
}
/**
* Constructs a GBC with given gridx, gridy, gridwidth, gridheight and all
* other grid bag constraint values set to the default.
*
* @param gridx
* the gridx position
* @param gridy
* the gridy position
* @param gridwidth
* the cell span in x-direction
* @param gridheight
* the cell span in y-direction
*/
public GBC(int gridx, int gridy, int gridwidth, int gridheight) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth = gridwidth;
this.gridheight = gridheight;
}
/**
* Sets the anchor.
*
* @param anchor
* the anchor value
* @return this object for further modification
*/
public GBC setAnchor(int anchor) {
this.anchor = anchor;
return this;
}
/**
* Sets the fill direction.
*
* @param fill
* the fill direction
* @return this object for further modification
*/
public GBC setFill(int fill) {
this.fill = fill;
return this;
}
/**
* Sets the cell weights.
*
* @param weightx
* the cell weight in x-direction
* @param weighty
* the cell weight in y-direction
* @return this object for further modification
*/
public GBC setWeight(double weightx, double weighty) {
this.weightx = weightx;
this.weighty = weighty;
return this;
}
/**
* Sets the insets of this cell.
*
* @param distance
* the spacing to use in all directions
* @return this object for further modification
*/
public GBC setInsets(int distance) {
this.insets = new Insets(distance, distance, distance, distance);
return this;
}
/**
* Sets the insets of this cell.
*
* @param top
* the spacing to use on top
* @param left
* the spacing to use to the left
* @param bottom
* the spacing to use on the bottom
* @param right
* the spacing to use to the right
* @return this object for further modification
*/
public GBC setInsets(int top, int left, int bottom, int right) {
this.insets = new Insets(top, left, bottom, right);
return this;
}
/**
* Sets the internal padding
*
* @param ipadx
* the internal padding in x-direction
* @param ipady
* the internal padding in y-direction
* @return this object for further modification
*/
public GBC setIpad(int ipadx, int ipady) {
this.ipadx = ipadx;
this.ipady = ipady;
return this;
}
}
运行以上程序得到的结果如下图所示:
这里有个问题是发送邮件时邮件服务器要求进行认证,所以要将用户名与密码经过Base64编码之后才能发送。上面程序中的“aHhsMD?yMA==和“aHV4aWFvbGU?ODIx?jg0MQ==”就是我的邮箱用户名与密码分别经过Base64编码后得到的数据(仅作举例,与原数据不一致的,避免泄露隐私)。Base64编码的程序如下所示:
import java.io.*;
import sun.misc.BASE64Encoder;
public class Base64Encoding {
public static void main(String[] args) throws IOException {
BASE64Encoder encoder = new BASE64Encoder();
System.out.println("Please enter you userName:");
String username = new BufferedReader(new InputStreamReader(System.in))
.readLine();
System.out.println(encoder.encode(username.getBytes()));
System.out.println("Please enter you password:");
String password = new BufferedReader(new InputStreamReader(System.in))
.readLine();
System.out.println(encoder.encode(password.getBytes()));
}
}
3.4 建立URL连接
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import sun.misc.BASE64Encoder;
public class URLConnectionTest {
public static void main(String[] args) {
try {
String urlName;
if (args.length > 0)
urlName = args[0];
else
urlName = "http://www.baidu.com";
URL url = new URL(urlName);
URLConnection connection = url.openConnection();
// set username,password if specified on command line.
if (args.length > 2) {
String username = args[1];
String password = args[2];
String input = username + ":" + password;
String encoding = new BASE64Encoder().encode(input.getBytes());
connection.setRequestProperty("Authorization", "Basic"
+ encoding);
}
connection.connect();
// print header fields
Map<String, List<String>> headers = connection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
String key = entry.getKey();
for (String value : entry.getValue()) {
System.out.println(key + ":" + value);
}
}
// print convenience functions
System.out.println("-------------------------");
System.out.println("getContentType:" + connection.getContentType());
System.out.println("getContentLength:"
+ connection.getContentLength());
System.out.println("getContentEncoding:"
+ connection.getContentEncoding());
System.out.println("getDate:" + connection.getDate());
System.out.println("getExpiration:" + connection.getExpiration());
System.out
.println("getLastModifed:" + connection.getLastModified());
System.out.println("-------------------------");
Scanner in = new Scanner(connection.getInputStream());
// print first ten lines of contents
for (int n = 1; in.hasNextLine() && n <= 10; n++) {
System.out.println(in.nextLine());
}
if (in.hasNextLine())
System.out.println("......");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
提交表单数据
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* This program demostrates how to use the URLConnection class for a POST
* request.
*
*/
public class PostTest {
public static void main(String[] args) {
JFrame frame = new PostTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class PostTestFrame extends JFrame {
public static final int DEFAULT_WIDTH = 400;
public static final int DEFAULT_HEIGHT = 300;
private static String[] countries = { "Afghanistan", "Albania", "Algeria",
"American Samoa", "Andorra", "Angola", "Anguilla",
"Antigua and Barbuda", "Argentina", "Armenia", "Aruba",
"Australia", "Austria", "Azerbaijan", "Bahamas, The", "Bahrain",
"Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin",
"Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina",
"Botswana", "Brazil", "Brunei", "Bulgaria", "Burkina Faso",
"Burma", "Burundi", "Cambodia", "Cameroon", "Canada", "Cape Verde",
"Cayman Islands", "Central African Republic", "Chad", "Chile",
"China", "Colombia", "Comoros", "Congo (Brazzaville)",
"Congo (Kinshasa)", "Cook Islands", "Costa Rica", "Cote d'Ivoire",
"Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic",
"Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador",
"Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia",
"Ethiopia", "Faroe Islands", "Fiji", "Finland", "France",
"French Polynesia", "Gabon", "Gambia, The", "Gaza Strip",
"Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland",
"Grenada", "Guam", "Guatemala", "Guernsey", "Guinea",
"Guinea-Bissau", "Guyana", "Haiti", "Honduras", "Hong Kong",
"Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq",
"Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan",
"Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati",
"Korea, North", "Korea, South", "Kosovo", "Kuwait", "Kyrgyzstan",
"Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya",
"Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia",
"Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta",
"Marshall Islands", "Mauritania", "Mauritius", "Mayotte", "Mexico",
"Micronesia, Federated States of", "Moldova", "Monaco", "Mongolia",
"Montenegro", "Montserrat", "Morocco", "Mozambique", "Namibia",
"Nauru", "Nepal", "Netherlands", "New Caledonia", "New Zealand",
"Nicaragua", "Niger", "Nigeria", "Northern Mariana Islands",
"Norway", "Oman", "Pakistan", "Palau", "Panama",
"Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland",
"Portugal", "Puerto Rico", "Qatar", "Romania", "Russia", "Rwanda",
"Saint Barthelemy", "Saint Helena", "Saint Kitts and Nevis",
"Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon",
"Saint Vincent and the Grenadines", "Samoa", "San Marino",
"Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia",
"Seychelles", "Sierra Leone", "Singapore", "Sint Maarten",
"Slovakia", "Slovenia", "Solomon Islands", "Somalia",
"South Africa", "Spain", "Sri Lanka", "Sudan", "Suriname",
"Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan",
"Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo",
"Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
"Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Uganda",
"Ukraine", "United Arab Emirates", "United Kingdom",
"United States", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela",
"Vietnam", "Virgin Islands, British", "Virgin Islands, U.S.",
"Wallis and Futuna", "West Bank", "Western Sahara", "Yemen",
"Zambia", "Zimbabwe" };
public PostTestFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setTitle("PostTest");
JPanel northPanel = new JPanel();
add(northPanel, BorderLayout.NORTH);
final JComboBox combo = new JComboBox();
for (int i = 0; i < countries.length; i += 2) {
combo.addItem(countries[i]);
}
northPanel.add(combo);
final JTextArea result = new JTextArea();
add(new JScrollPane(result));
JButton getButton = new JButton("Get");
northPanel.add(getButton);
getButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
new Thread(new Runnable() {
public void run() {
// 以下网址可能变了,这里仅作示例用.
final String SERVER_URL = "http://www.census.gov/population/international/data/idb/informationGateway.php";
result.setText("");
Map<String, String> post = new HashMap<String, String>();
post.put("tbl", "001");
post.put("cty",
countries[2 * combo.getSelectedIndex() + 1]);
post.put("opty", "lastest checked");
try {
result.setText(doPost(SERVER_URL, post));
} catch (IOException e) {
result.setText("" + e);
}
}
}).start();
}
});
}
public String doPost(String urlString, Map<String, String> nameValuePairs)
throws IOException {
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
PrintWriter out = new PrintWriter(connection.getOutputStream());
boolean first = true;
for (Map.Entry<String, String> pair : nameValuePairs.entrySet()) {
if (first)
first = false;
else
out.print('&');
String name = pair.getKey();
String value = pair.getValue();
out.print(name);
out.print("=");
out.print(URLEncoder.encode(value, "UTF-8"));
}
out.close();
Scanner in;
StringBuilder responseStr = new StringBuilder();
try {
in = new Scanner(connection.getInputStream());
} catch (IOException e) {
// e.printStackTrace();
if (!(connection instanceof HttpURLConnection))
throw e;
InputStream err = ((HttpURLConnection) connection).getErrorStream();
if (err != null)
throw e;
in = new Scanner(err);
}
while (in.hasNextLine()) {
responseStr.append(in.nextLine());
responseStr.append("\n");
}
in.close();
return responseStr.toString();
}
}
3.5 高级套接字编程
3.5.1 套接字超时
针对不同的应用,应该设置合理的超时时间,如下所示:
Socket s=new Socket(...);
s.setSoTimeout(10000);//time out after 10 seconds
如果已经设置了超时值,并且读操作与写操作在完成前超过了超时值,那么程序会抛出SocketTimeoutException异常。可以捕获这个异常,如下所示:
try{
Scanner in=new Scanner(s.getInputStream());
String line=in.nexLine();
...
}catch(InterruptedIOException e){
react to timeout
}
另外,还有一个超时问题是我们经常遇到的,比如:
Socket(String host,int port);
这行代码会导致一直无限期等待下去,直到建立了到达主机的初始连接为止。针对这个问题,我们可以先通过构建一个无连接的套接字,然后再使用一个超时来进行连接的方法来解决这个问题。
Socket s=new Socket();
s.connect(new InetSocketAddress(host,port),timeout);
3.5.2 可中断套接字
import java.net.*;
import java.nio.channels.SocketChannel;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* This program shows how to interrupt a socket channel.
*
*/
public class InterruptibleSocketTest {
public static void main(String[] args) {
JFrame frame = new InterruptibleSocketFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class InterruptibleSocketFrame extends JFrame {
public static final int WIDTH = 300;
public static final int HEIGHT = 300;
private Scanner in;
private PrintWriter out;
private JButton startButton;
private JButton cancelButton;
private JCheckBox busyBox;
private JTextArea messages;
private TestServer server;
private Thread connectThread;
public InterruptibleSocketFrame() {
setSize(WIDTH, HEIGHT);
setTitle("InterruptibleSocketTest");
JPanel northPanel = new JPanel();
add(northPanel, BorderLayout.NORTH);
messages = new JTextArea();
add(new JScrollPane(messages));
busyBox = new JCheckBox("Busy");
northPanel.add(busyBox);
startButton = new JButton("Start");
northPanel.add(startButton);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
startButton.setEnabled(false);
cancelButton.setEnabled(true);// 变可用
connectThread = new Thread(new Runnable() {
public void run() {
connect();
}
});
connectThread.start();
}
});
cancelButton = new JButton("Cancel");
cancelButton.setEnabled(false);// 刚开始不可用
northPanel.add(cancelButton);
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// 这里强行中止,如果后面的套接字是不可中断的,那么操作是无效的.
connectThread.interrupt();
startButton.setEnabled(true);
cancelButton.setEnabled(false);
}
});
new Thread(new TestServer()).start();// 启动处理线程
}
public void connect() {
try {
// 可中断套接字
SocketChannel channel = SocketChannel.open(new InetSocketAddress(
"localhost", 8189));
try {
// 此时如果线程中断,那么这些操作将不会陷入阻塞,而是以抛异常的方式结束.
in = new Scanner(channel);
while (true) {
if (in.hasNextLine()) {
String line = in.nextLine();
messages.append(line);
messages.append("\n");
} else {
Thread.sleep(100);
}
}
} finally {
channel.close();
messages.append("Socket closed\n");
}
} catch (IOException e) {
messages.append("\nInterruptibleSocketTest.connect:" + e);
} catch (InterruptedException e) {
messages.append("\nInterruptibleSocketTest.connect:" + e);
}
}
/**
* A mutithread server that listens to port 8189 and sends random numbers to
* the client.
*
*/
class TestServer implements Runnable {
public void run() {
try {
ServerSocket s = new ServerSocket(8189);
while (true) {
Socket incoming = s.accept();
Runnable r = new RandomNumberHandler(incoming);
Thread t = new Thread(r);
t.start();
}
} catch (IOException e) {
messages.append("\nTestServer.run:" + e);
}
}
}
/**
* Thist class handles the client input for one server socket connection.
*
*/
class RandomNumberHandler implements Runnable {
private Socket incoming;
public RandomNumberHandler(Socket i) {
incoming = i;
}
public void run() {
try {
OutputStream outStream = incoming.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true/* autoFlush */);
Random generator = new Random();
while (true) {
if (!busyBox.isSelected())
out.println(generator.nextInt());
Thread.sleep(100);// 选busy时,一直睡下去
}
} catch (IOException e) {
messages.append("\nRandomNumberHandler.run:" + e);
} catch (InterruptedException e) {
messages.append("\nRandomNumberHandler.run:" + e);
}
}
}
}
程序运行的结果如下图所示:
3.5.3 半关闭
半关闭:通过关闭一个套接字的输出流来表示发送给服务器的请求数据已经结束,但是必须保留输入流打开以读取服务器的响应信息。以下代码演示了如何在客户端使用半关闭方法:
Socket socket=new Socket(host,port);
Scanner in=new Scanner(socket.getInputStream));
PrintWriter writer=new PrintWriter(socket.getOutputStream));
//send request data
writer.print(...);
writer.flush();
socket.shutdownOutput();
//now socket is half closed
//read response data
while(in.hasnextLine()!=null){
String line=in.nextLine();
......
}
socket.close();
3.5.4 因特网地址
import java.net.InetAddress;
/**
* This program demostrates InetAddress class. supply a host name as
* command-line arguments,or run whthout command-line arguments to see the
* address of the local host
*
*/
public class InetAddressTest {
public static void main(String[] args) {
try {
if (args.length > 0) {
String host = args[0];
InetAddress[] address = InetAddress.getAllByName(host);
for (InetAddress a : address) {
System.out.println(a);
}
} else {
InetAddress localHostAddress = InetAddress.getLocalHost();
System.out.println(localHostAddress);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}