赞
踩
InetAddress
类主要是用来得到所指定的网络地址InetAddress
类没有直接显式的构造函数。要生成一个InetAddress对象,必须运用一个可用的工厂方法。工厂方法(factory method
)仅是一个类中的静态方法返回一个该类实例的约定。这是在一个带有各种参数列表的重载构造函数中完成的,当持有惟一方法名时可使结果更清晰。InetAddress
有三个方法可以用来创建InetAddress
的实例
static InetAddress getLocalHost( ) throws UnknownHostException
static InetAddress getByName(String hostName) throws UnknownHostException
static InetAddress[ ] getAllByName(String hostName) throws UnknownHostException
boolean equals(Object other)
byte[ ] getAddress( )
String getHostAddress( )
String getHostName( )
int hashCode( )
boolean isMulticastAddress( )
String toString( )
Protocol://hostname:port/resourcename#anchor
,即 协议://主机名:端口/资源名#标记
URL urlBase=new URL("http://www. 263.net/");
URL url=new URL("http", "www.gamelan.com", "/pages/Gamelan.net. html");
URL gamelan=new URL("http", "www.gamelan.com", 80, "Pages/Gamelan.network.html");
public String getProtocol()
获取该URL的协议名。public String getHost()
获取该URL的主机名。public int getPort()
获取该URL的端口号,如果没有设置端口,返回-1。public String getFile()
获取该URL的文件名。public String getQuery()
获取该URL的查询信息。public String getPath()
获取该URL的路径。public String getAuthority()
获取该URL的权限信息。public String getUserInfo()
获得使用者的信息。public String getRef()
获得该URL的引用。URL类经常用于下载网络资源,URL通过构造函数(构造函数为URL地址)可以得到一个对象,该对象的openStream()方法可以得到InputStream对象,得到InputStream就可以把网站上的资源下载下来了
下面是一个实例,使用URL类下载某个网站上的一张图片并保存到本地。
import java.net.*; import java.io.*; public class TestURL { public static void main(String aregs[ ])throws Exception { URL url=new URL("http://images.sohu.com/uiue/sohu_logo/beijing2008/sohu.gif"); InputStream in=url.openStream(); FileOutputStream fout=new FileOutputStream(new File("sohu.gif")); int a=0; while(a>-1) { a=in.read(); fout.write(a); } } }
运行成功后,在当前目录生成一个gif图片
String getHeaderField(String name)
InputStream getInputStream()
String getContentEncoding()
int getContentLength()
String getContentType()
long getDate()
使用InetAddress类的方法获取本地机的名称和IP地址
package com.ipaddress; import java.net.*; public class IPAddress { public static void main(String[] args) { try { InetAddress inetAddress = InetAddress.getLocalHost(); String hostName = inetAddress.getHostName(); String hostAddress = inetAddress.getHostAddress(); System.out.println(hostName); System.out.println(hostAddress); } catch (UnknownHostException e) { e.printStackTrace(); } } }
打印结果:
MacBook-Air.local
192.168.0.101
使用InetAddress类的方法获取网站www.csdn.net的IP地址,如果存在多个IP地址,要求全部返回。
package com.ipaddress; import java.net.*; public class CSDNAddress { public static void main(String[] args) { try { InetAddress[] inetAddresses = InetAddress.getAllByName("www.csdn.net"); for (InetAddress inetAddress: inetAddresses) { String hostName = inetAddress.getHostName(); String hostAddress = inetAddress.getHostAddress(); System.out.println(hostName + " " + hostAddress); } } catch (UnknownHostException e) { e.printStackTrace(); } } }
打印结果
www.csdn.net 39.106.226.142
使用URL类下载深圳大学首页http://www.szu.edu.cn,并统计下载得到网页文件的大小
package com.ipaddress; import java.net.*; import java.io.*; public class SZUurl { public static void main(String[] args) throws Exception { URL url = new URL("http://www.szu.edu.cn"); URLConnection connection = url.openConnection(); int size = connection.getContentLength(); InputStream in = url.openStream(); FileOutputStream fout = new FileOutputStream(new File("szu.html")); int a = 0; while(a > -1) { a = in.read(); fout.write(a); } fout.close(); System.out.println(size + "B"); } }
打印结果
137 B
此时目录结构,可以看到szu.html
文件在此目录下
$ tree . ├── Network.iml ├── out │ └── production │ └── Network │ └── com │ └── ipaddress │ ├── CSDNAddress.class │ ├── IPAddress.class │ └── SZUurl.class ├── src │ └── com │ └── ipaddress │ ├── CSDNAddress.java │ ├── IPAddress.java │ └── SZUurl.java └── szu.html 8 directories, 8 files
cmd > netstat –na
可以查看本机的端口使用情况。
Socket是网络上运行的程序之间双向通信链路的最后终结点
IP与端口的组合得出一个套接字,可以完全分辨Internet上运行的程序
概述
Socket类的构造方法:
public Socket(String host, int port)
public Socket(InetAddress address, int port)
public Socket(String host, int port, InetAddress localAddr, int localPort)
//在指定的机器上的指定端口上运行
上述方法都将抛出例外IOException,程序中需要捕获处理。
Socket的常见方法:
//Socket的输入/输出流管理;抛出例外IOException。
public InputStream getInputStream()
public void shutdownInput()
public OutputStream getOutputStream()
public void shutdownOutput()
//关闭Socket
public void close() throws IOException
//设置/获取Socket数据:
public InetAddress getInetAddress() 返回此套接字链接的地址对象
public InetAddress getLocalAddress() 返回此套接字本地的地址对象
public int getPort() 返回此套接字链接地址的端口
上述方法都将抛出例外SocketException,程序中需要捕获处理。
构造方法:
public ServerSocket(int port)
public ServerSocket(int port, int backlog) //支持指定数目的连接
public ServerSocket(int port, int backlog, InetAddress bindAddr) //在指定的机器上运行
主要方法
public Socket accept():等待客户端的连接
public void close():关闭Socket
设置/获取Socket数据的方法
public InetAddress getInetAddress()
public int getLocalPort(), ...
Socket通信程序基本结构都一样,包括以下四个基本步骤:
通常,程序员的主要工作是针对所要完成的功能在第3步进行编程,第1、2、4步对所有的通信程序来说几乎都是一样的。
创建Socket
下面是一个典型的创建客户端Socket的代码:
try
{
Socket socket=new Socket("127.0.0.1",1432);
//127.0.0.1是TCP/IP协议中默认的本机地址
}catch(IOException e){
System.out.println("Error:"+e);
}
创建服务器应用程序
用于服务器的类和方法
ServerSocket类
创建服务器
构造函数的代码给出如下:
try {
server = new ServerSocket(1432);
//创建一个ServerSocket在端口1432监听客户请求
} catch (Exception e) {
System.out.println("can not listen to:" + e);
//出错,打印出错信息
}
System.out.println("Server started…");
this.start(); //启动线程
监听客户请求
ServerSocket对象通过accept()方法来监听客户的请求,如果接收到客户的请求,则产生一个Socket对象,并继续执行后面的代码;如果没有接收到客户请求,则产生一个错误信息。
Socket socket = null;
try {
socket = server.accept();
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
} catch (Exception e) {
System.out.println("can not listen to:" + e);
//出错,打印出错信息
}
服务器的输入和输出流
服务器端用到了以下的输入和输出流:
``java
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter os = new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
{
new Server();
}
完整的服务器程序
ObjectInputStream类
ObjectInputStream类中包含从持久的存储介质中读出类的对象的功能。持久的存储介质可以是磁盘或套接字。
这由ObjectInputStream类的readObject()方法来完成。readObject()方法的语法如下:
FileInputStream fp=new FileInputStream(“data.txt”);
ObjectInputStream istream = new ObjectInputStream(fp);
Date date = (Date)istream.readObject();
一般步骤
UDP通信是一种无连接的数据报通信。使用该协议,两个程序进行通信时不用建立连接;数据以独立的包为单位发送,包的容量限定在64KB以内;每个数据报需要有完整的收/发地址,可以随时进行收/发数据报,但不保证传送顺序和内容准确;数据报可能会被丢失、延误等。UDP通信是不可靠的通信,但通信速度较快,常常被应用在某些要求实时交互,准确性要求不高,但传输速度要求较高的场合(如视频会议系统等)。
Java中,基于UDP协议实现网络通信的类有三个:
用于表示通信数据的数据报类:DatagramPacket
用于进行端到端通信的类:DatagramSocket
用于广播通信的类:MulticastSocket。
用DatagramPacket类将数据打包,即创建数据包对象。
DatagramPacket(byte data[], int length, InetAddtress address,int port)
Address: 目标主机地址 Port:目标主机端口
如:
byte data[]=“近来好吗”.getByte();
InetAddress address=inetAddress.getByname(www.sina.com.cn);
DatagramPacket data_pack=new DatagramPacket(data,data.length,address,980);
注: data_pack常用方法:
用DatagramSocket类的构造方法DatagramSocket()创建一个对象,该对象负责发送数据包。例:
DatagramSocket mail_in=new DatagramSocket(int port);
注意:mail_in的主要方法:
利用Socket类和ServerSocket类编写一个C/S程序,实现C/S通信。
客户端向服务器端发送Time命令,服务器端接受到该字符串后将服务器端当前时间返回给客户端;客户端向服务器端发送Exit命令,服务器端向客户端返回“Bye”后退出。
编写完整程序;一个服务器端程序,一个客户端程序。服务器端和客户端都需要打印出接受到的消息和发出的命令。
下图为运行结果示例
Server.java
:
package com.csmode; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Calendar; public class Server { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket; DataOutputStream dataOutputStream; DataInputStream dataInputStream; System.out.println("Server Running ... "); String time; String goodbye = "Bye!"; String error = "No such Command!"; try { //在端口号4096创建 serverSocket serverSocket = new ServerSocket(4096); } catch (IOException e) { System.out.println("ServerSocket error"); e.printStackTrace(); } try { assert serverSocket != null; socket = serverSocket.accept(); // 连接成功 dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream.writeUTF("服务器启动完毕\n创建客户连接\t\t"); // 标记什么时候退出 boolean flag = true; while(flag) { // 接收客户端发送过来的消息 dataInputStream = new DataInputStream(socket.getInputStream()); String str = dataInputStream.readUTF(); System.out.print(str + " : "); if(str.equals("Time")) { time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); dataOutputStream.writeUTF("服务器当前时间为:\t" + time); System.out.println(time); } else if (str.equals("Exit")) { dataOutputStream.writeUTF(goodbye); flag = false; } else { dataOutputStream.writeUTF(error); } } } catch (IOException e) { System.out.println("Socket data IO error"); e.printStackTrace(); } } }
Client.java
:
package com.csmode; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Scanner; public class Client { public static void main(String[] args) { try { Socket socket = new Socket("localhost", 4096); // 创建 Socket 管道 DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); String string = dataInputStream.readUTF(); System.out.println(string); while(true) { // 输入命令 Scanner input = new Scanner(System.in); String str = input.next(); dataOutputStream.writeUTF(str); // 在服务器端传来的 数据 string = dataInputStream.readUTF(); System.out.println(string); if(str.equals("Exit")) { break; } } } catch (IOException e) { e.printStackTrace(); } } }
先启动Server.java
, 再启动Client.java
结果如下:
客户端:
服务器端:
编写一数据报通信程序,实现简单的聊天功能。
“聊天内容”和“输入文本”分别为当前聊天的历史信息和当前要传送出去的聊天文本。“确定”、“清空”、“退出”三个按钮分别实现发送当前聊天文本、清空当前聊天文本和退出系统的功能。
界面可参考如下格式
PID.java
package com.chattingroom;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
public class PID {
// 获取 PID
public static int getProcessID() {
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
return Integer.parseInt(runtimeMXBean.getName().split("@")[0]);
}
}
chat.java
package com.chattingroom; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.TextArea; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; public class chat extends JFrame implements ActionListener, Runnable, KeyListener { private TextArea textArea; private JTextField sendText; private JTextField ip; private JTextField port; private JButton buttonServer; private JButton buttonClient; private JButton send; private JButton exit; private JButton clear; private Socket socket; public void keyReleased(KeyEvent f) { } // 监听键盘输入 public void keyPressed(KeyEvent f) { if (f.getKeyCode() == KeyEvent.VK_ENTER) { PrintWriter printWriter = null; try { printWriter = new PrintWriter(socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } String string = sendText.getText(); if (string == null) return; int pid = PID.getProcessID(); String User = ip.getText() + " : " + port.getText(); // 自己发的消息 textArea.append(User + " : " + pid + " says: " + "\n" + string + "\n"); // 对面发来的消息 String string3 = User + " : " + pid + " says: " + "\n" + string; assert printWriter != null; printWriter.println(string3); printWriter.flush(); sendText.setText(""); } } public void keyTyped(KeyEvent f) { } // 轮询 public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { String string = br.readLine(); if (string == null) break; textArea.append(string + "\n"); } } catch (Exception e) { e.printStackTrace(); } } public void actionPerformed(ActionEvent e) { if (e.getSource() == buttonServer) { server(); } if (e.getSource() == buttonClient) { client(); } if (e.getSource() == send) { doSend(); } if (e.getSource() == exit) { doExit(); } if (e.getSource() == clear) { doClear(); } } // 作为服务器启动 public void server() { try { ServerSocket server = new ServerSocket(Integer.parseInt(port.getText())); socket = server.accept(); textArea.append("连接服务器成功!\n"); new Thread(this).start(); } catch (Exception e) { textArea.append("服务器启动失败!\n"); } } // 作为客户端启动 public void client() { try { socket = new Socket(ip.getText(), Integer.parseInt(port.getText())); textArea.append("连接服务器成功!\n"); new Thread(this).start(); } catch (Exception e) { textArea.append("连接失败!\n"); } } // 发送消息 public void doSend() { try { PrintWriter printWriter = new PrintWriter(socket.getOutputStream()); String string = sendText.getText(); if (string == null) return; int pid = PID.getProcessID(); String User = ip.getText() + " : " + port.getText(); // 自己发的消息 textArea.append(User + " : " + pid + " says: " + "\n" + string + "\n"); // 对面发来的消息 String string3 = User + " : " + pid + " says: " + "\n" + string; printWriter.println(string3); printWriter.flush(); sendText.setText(""); } catch (Exception e) { textArea.append("发送失败!\n"); } } // 清除聊天 public void doClear() { textArea.setText(""); } // 退出程序 public void doExit() { System.exit(0); } // 连接键 public void addClient(JPanel panel) { buttonClient = new JButton("连接"); buttonClient.setForeground(new Color(250, 131, 46)); buttonClient.setFont(new Font("宋体", Font.BOLD, 14)); panel.add(buttonClient); } // 监听键 public void addServer(JPanel panel) { buttonServer = new JButton("监听"); buttonServer.setForeground(new Color(250, 131, 46)); buttonServer.setFont(new Font("宋体", Font.BOLD, 14)); panel.add(buttonServer); } // 清除键 public void addClear(JPanel panel) { clear = new JButton("清除"); clear.setForeground(new Color(250, 131, 46)); clear.setFont(new Font("宋体", Font.BOLD, 14)); panel.add(clear); } // 退出键 public void addExit(JPanel panel) { exit = new JButton("退出"); exit.setForeground(new Color(250, 131, 46)); exit.setFont(new Font("宋体", Font.BOLD, 14)); panel.add(exit); } // 设置 JPanel public void setPanel(JPanel panel) { panel.setLayout(new BorderLayout()); panel.add(ip, BorderLayout.WEST); panel.setBackground(new Color(245, 161, 102)); sendText = new JTextField(""); panel.add(sendText, BorderLayout.CENTER); send = new JButton("发送"); panel.add(send, BorderLayout.EAST); } // 设置按键监听 public void setListen() { clear.addActionListener(this); exit.addActionListener(this); buttonServer.addActionListener(this); buttonClient.addActionListener(this); send.addActionListener(this); sendText.addKeyListener(this); } public JPanel setJPanel1(Container container) { JPanel panel = new JPanel(); container.add(panel, BorderLayout.NORTH); panel.setBackground(new Color(231, 162, 112)); textArea = new TextArea(); container.add(textArea, BorderLayout.CENTER); return panel; } public JPanel setJPanel2(Container container) { JPanel panel = new JPanel(); container.add(panel, BorderLayout.SOUTH); panel.setBackground(new Color(250, 180, 30)); textArea.setForeground(new Color(250, 131, 46)); return panel; } public void addButton(JPanel panel){ addServer(panel); addClient(panel); addClear(panel); addExit(panel); } // 聊天界面 public chat(String IPAddress, String Port) { this.setTitle("UDP聊天程序"); this.setBounds(200, 200, 500, 500); Container container = this.getContentPane(); JPanel panel1 = setJPanel1(container); JPanel panel2 = setJPanel2(container); ip = new JTextField(IPAddress, 15); port = new JTextField(Port, 4); addButton(panel1); setPanel(panel2); setListen(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
Run.java
package com.chattingroom;
public class Run {
public static void main(String[] args) {
new chat("127.0.0.1", "8192").setVisible(true);
}
}
目录结构如下:
$ tree chattingroom
chattingroom
├── PID.java
├── Run.java
└── chat.java
开启两个程序运行,效果如下:
左端输入123,右端输入456,结果如下:
利用Socket类和ServerSocket类,编写一个C/S程序,实现网络文件传输。
客户端向服务器端发送请求,服务器端当接受到客户端的请求之后,先向其传输文件名,当客户端接受完毕之后,向客户端传输文件
客户端连上服务器后接收传输文件,并进行改名(文件名可自行定义)存在本地。
编写完整程序;一个服务器端程序,一个客户端程序。服务器端和客户端都需要打印出交互过程。
下图为运行结果示例
服务器端运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V42P3IHL-1648993394649)(https://cdn.jsdelivr.net/gh/Misaka-9982-coder/img_hosting/img/image-20220403132839233.png)]
客服端运行结果:
Server.java
package com.Transmission; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server implements Runnable { private static final int Port = 4096; private static final int TTL = 20; private final Socket socket; String fileName = "test.txt"; public Server(Socket socket) { super(); this.socket = socket; } public static void server() { try { ServerSocket serverSocket = new ServerSocket(Port); int i = 0; do { i ++ ; Socket socket = serverSocket.accept(); System.out.println("服务器的线程1,启动,与客户端" + i + "连接成功"); new Thread(new Server(socket)).start(); } while (i <= TTL); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { OutputStream outputStream = null; FileInputStream fileInputStream = null; try { outputStream = socket.getOutputStream(); System.out.println("要传输的文件为: " + fileName); outputStream.write(fileName.getBytes()); System.out.println("开始传输文件"); fileInputStream = new FileInputStream(fileName); int data; while (-1 != (data = fileInputStream.read())) { outputStream.write(data); } System.out.println("文件传输结束"); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileInputStream != null) fileInputStream.close(); if (outputStream != null) outputStream.close(); this.socket.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Server.server(); } }
Client.java
package com.Transmission; import java.io.*; import java.net.InetSocketAddress; import java.net.Socket; public class Client { private static final String SERVERIP = "localhost"; private static final int Port = 4096; private static final int clientPort = 8192; public static void main(String[] args) { byte[] buffer = new byte[2048]; Socket socket = new Socket(); try { socket.connect(new InetSocketAddress(SERVERIP, Port), clientPort); System.out.println("与服务器连接成功"); InputStream inputStream = socket.getInputStream(); int read = inputStream.read(buffer); String fileName = new String(buffer, 0, read); String newName = "test1.txt"; FileOutputStream fileOutputStream = new FileOutputStream(newName); int data; while ((data = inputStream.read()) != -1) { fileOutputStream.write(data); } System.out.println("接收到的文件为:" + fileName); System.out.println("保存为为:" + newName); inputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
结果:
客户端:
服务器端:
现在文件结构如下:
$ tree . . ├── Network.iml ├── out │ └── production │ └── Network │ └── com │ ├── Transmission │ │ ├── Client.class │ │ └── Server.class │ ├── chattingroom │ │ ├── PID.class │ │ ├── Run.class │ │ └── chat.class │ ├── csmode │ │ ├── Client.class │ │ └── Server.class │ └── ipaddress │ ├── CSDNAddress.class │ ├── IPAddress.class │ └── SZUurl.class ├── src │ └── com │ ├── Transmission │ │ ├── Client.java │ │ └── Server.java │ ├── chattingroom │ │ ├── PID.java │ │ ├── Run.java │ │ └── chat.java │ ├── csmode │ │ ├── Client.java │ │ └── Server.java │ └── ipaddress │ ├── CSDNAddress.java │ ├── IPAddress.java │ └── SZUurl.java ├── szu.html ├── test.txt └── test1.txt 14 directories, 24 files
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。