IP Address
网络编程模型
InetAddress
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
InetAddress类的非静态方法
boolean equals(Object other) 如果对象具有和other相同的Internet地址则返回true。byte[ ] getAddress( ) 返回此InetAddress对象的原始 IP 地址。String getHostAddress( ) 返回与InetAddress对象相关的主机地址的字符串。String getHostName( ) 返回与InetAddress对象相关的主机名的字符串。int hashCode( ) 返回调用对象的散列码。boolean isMulticastAddress( ) 如果Internet地址是一个多播地址则返回true;否则返回false。String toString( ) 返回主机名字符串和IP地址。
URL
- URL类封装了使用统一资源定位器(Uniform Resource Locator)访问一个WWW上的资源的方法。这个类可以生成一个寻址或指向某个资源的对象。URL类生成的对象指向WWW资源(Web页、文本文件、图形文件、声频片段等等)
- URL的基本表示方法是:
Protocol://hostname:port/resourcename#anchor ,即 协议://主机名:端口/资源名#标记
构造方法
- public URL (String spec)
- 通过一个表示URL地址的字符串可以构造一个URL对象。如以下语句:
URL urlBase=new URL("http://www. 263.net/"); - public URL(URL context, String spec)
- 通过基URL和相对URL构造一个URL对象。如以下语句:
- `URL net263=new URL (“http://www.263.net/”);``
- ``URL index263=new URL(net263, “index.html”)`
- public URL(String protocol, String host, String file);
URL url=new URL("http", "www.gamelan.com", "/pages/Gamelan.net. html"); - public URL(String protocol, String host, int port, String file);
URL gamelan=new URL("http", "www.gamelan.com", 80, "Pages/Gamelan.network.html");
URL常用方法
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通过构造函数(构造函数为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图片
URLConnection
- URL类中的openConnection()方法可生成一个URLConnection对象,URLConnection类的实例可用于读取和写入此URL引用的资源。
- 在网络编程工作中,JAVA的URLConnection是一个常用的类,它提供了一个非常方便的接口,只要提供需要连接的主机的URL地址,使用URL类的openConnection()方法就可以得到一个HttpURLConnection的对象,其中HttpURLConnection类是URLConnection类的子类,然后在此基础上分析HTTP内容,完成相关任务。在这种方式下,使用者不必考虑底层的实现细节,避免了烦琐的Socket类的代码编写,因此比较常用。
URLConnection常用方法
String getHeaderField(String name) 返回指定的头字段的值。InputStream getInputStream() 返回在此打开的连接读取的输入流。String getContentEncoding() 返回content-encoding头字段的值。int getContentLength() 返回content-length头字段的值。String getContentType() 返回content-type头字段的值。long getDate() 返回date头字段的值。
练习
-
使用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
网络聊天室
套接字(Socket)
- 用于实现网络上客户端程序和服务器程序之间的连接。
- 套接字负责网络上进程之间的通信
- 客户端程序可以向套接字里写入请求,然后服务器会处理这个请求,并把处理结果通过套接字送回。
- 服务器应用程序一般会侦听一个特定端口,用来等待客户的连接请求,当一个连接请求到达时,客户和服务器会建立一个通信连接,在连接过程中,客户被分配一个本地端口号并与一个Socket连接,客户通过写Socket来通知服务器,再通过读取Socket来获取服务器发送过来的信息。
- 类似地,服务器也获取一个本地端口号,它需要一个新的端口号来侦听原始端口上的其他连接请求。服务器也给它的本地端口连接一个Socket,通过读写它来与客户通信。
- Socket可以根据通信性质分类,这种性质对于用户是可见的。
- 应用程序一般仅在同一类的套接字之间进行通信。不过只要底层的通信协议允许,不同类型的套接字之间也可以通信。
- 目前可以使用两种套接字,即流套接字和数据报套接字。
- 流套接字提供了双向的、有序的、无重复的并且无记录边界的数据流服务。
- TCP是一种流套接字协议
- 数据报套接字支持双向的数据流,但并不保证是可靠、有序、无重复的,也就是说,一个以数据报套接字来接收信息的进程有可能发现信息重复了,或者和发出的顺序不同了。数据报套接字的一个重要特点是它保留了记录边界。
- UDP即是一种数据报套接字协议。
端口
- 是一个逻辑概念。每一个服务器都运行在该主机的一个对外开放的端口上。
- 一个主机上可以有多种服务器,也就是有多个端口。程序员可以在创建自己的服务器程序时使用其它端口(即除了系统默认的端口)。
- 端口常以数字编号,作为客户可指定一个端口号,用这个端口号来连接相应的服务器以接收服务。
- 如果把 IP 地址看作电话号码,则端口类似电话的分机号码
cmd > netstat –na 可以查看本机的端口使用情况。
Socket
Socket是网络上运行的程序之间双向通信链路的最后终结点
IP与端口的组合得出一个套接字,可以完全分辨Internet上运行的程序
Socket通信—TCP
- 一对一的Socket C/S通信
- TCP是一种可靠的、基于连接的网络协议,在Internet上大都采用TCP/IP协议进行互联。网络上的两个进程采用C/S模式进行通信。
- 当两台主机准备进行交谈时,都必须建立一个Socket,其中一方作为服务器打开一个Socket并侦听来自网络的连接请求,另一个作为客户,它向网络上的服务器发送请求,通过Socket与服务器传递信息,要建立连接,只需指定主机的IP地址和端口即可。
Socket 工作模式
使用TCP协议的Socket编程
-
概述
- Java提供Socket和ServerSocket类作为标准的TCP套接字编程技术,通过它们实现主机与主机之间(应用程序间)的对话。位于:java.net包中。
- 使用Socket进行C/S程序设计的一般连接过程:
- Server端Listen(监听)某个端口是否有连接请求,
- Client端向Server端发出Connect(连接)请求,
- Server端向Client端发回Accept(接受)消息。
- 连接建立后,Server端和Client端都可以通过套接字类提供的一些方法与对方通信。
-
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的常见方法:
public InputStream getInputStream()
public void shutdownInput()
public OutputStream getOutputStream()
public void shutdownOutput()
public void close() throws IOException
public InetAddress getInetAddress() 返回此套接字链接的地址对象
public InetAddress getLocalAddress() 返回此套接字本地的地址对象
public int getPort() 返回此套接字链接地址的端口
上述方法都将抛出例外SocketException,程序中需要捕获处理。 -
ServerSocket类 构造方法: 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通信程序基本结构都一样,包括以下四个基本步骤:
- 在客户方和服务器方创建Socket/ServerSocket实例。
- 打开连接到Socket的输入/输出流。
- 利用输入/输出流,按照一定的协议对Socket进行读/写操作。
- 关闭输入/输出流和Socket。
通常,程序员的主要工作是针对所要完成的功能在第3步进行编程,第1、2、4步对所有的通信程序来说几乎都是一样的。
Socket
数据报通讯(UDP)
概述
-
UDP通信是一种无连接的数据报通信。使用该协议,两个程序进行通信时不用建立连接;数据以独立的包为单位发送,包的容量限定在64KB以内;每个数据报需要有完整的收/发地址,可以随时进行收/发数据报,但不保证传送顺序和内容准确;数据报可能会被丢失、延误等。UDP通信是不可靠的通信,但通信速度较快,常常被应用在某些要求实时交互,准确性要求不高,但传输速度要求较高的场合(如视频会议系统等)。 -
Java中,基于UDP协议实现网络通信的类有三个:
-
用于表示通信数据的数据报类:DatagramPacket -
用于进行端到端通信的类:DatagramSocket -
用于广播通信的类:MulticastSocket。
基于UDP通信的基本模式
- 将数据打包,发往目的地
- 接受别人发来的数据包,察看数据包内容
发送数据包
-
用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常用方法:
- Public int getPort();
- public InetAddress getAddress();
- public byte[] getData();
-
用DatagramSocket类的构造方法DatagramSocket()创建一个对象,该对象负责发送数据包。例:
- DatagramSocket mail_out=new DatagramSocket();
- Mail_out.send(data_pack);
接收数据
DatagramSocket mail_in=new DatagramSocket(int port); 注意:mail_in的主要方法:
- Receive(DatagramPacket pack) //接收数据包给pack, 例如:
- DatagramPacket pack=new DatagramPacket(data,length)
- Mail_in.receive(pack);
练习
练习1
-
利用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 {
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);
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
结果如下:
客户端:
服务器端:
练习2
PID.java
package com.chattingroom;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
public class 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);
}
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,结果如下:
TCP 文件传输
Java对网络编程的支持
java.net包中的主要的类和可能产生的例外包括:
- 面向应用层的类:
- 面向传输层/IP层的类:
- TCP协议相关类:
- UDP协议相关类:
- DatagramPacket
- DatagramSocket
- MulticastSocket
- 表示IP 地址的类:
- 可能产生的异常:
- BindException
- ConnectException
- MalformedURLException
- NoRouteToHostException
- ProtocolException
- SocketException
- UnknownHostException
- UnknownServiceException
练习
-
利用Socket类和ServerSocket类,编写一个C/S程序,实现网络文件传输。 -
客户端向服务器端发送请求,服务器端当接受到客户端的请求之后,先向其传输文件名,当客户端接受完毕之后,向客户端传输文件 -
客户端连上服务器后接收传输文件,并进行改名(文件名可自行定义)存在本地。 -
编写完整程序;一个服务器端程序,一个客户端程序。服务器端和客户端都需要打印出交互过程。 -
下图为运行结果示例
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
|