JavaSE| 网络编程

URL

URI(Uniform resource identifier):表示一个统一资源标识符 (URI) 引用,用来唯一的标识一个资源。

URL(Uniform Resource Locator):类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URI不能用于定位任何资源,它的唯一作用是解析,而URL则包含一个可打开到达该资源的输入流。 URL的基本结构由5部分组成:

<传输协议>://<主机名>:<端口号>/<文件名>#片段名
<传输协议>://<主机名>:<端口号>/<文件名>?参数列表

其中#片段名:即锚点,例如看小说,直接定位到章节

例如:http://java.sun.com/index.html#chapter1

参数列表格式:参数名=参数值&参数名=参数值....

例如: http://192.168.1.100:8080/helloworld/index.jsp?username=chai&password=123

URL url = new URL("http://www.baidu.com:80/index.html?keyword=java");
System.out.println("协议:" + url.getProtocol());
System.out.println("主机名:" + url.getHost());
System.out.println("端口号:" + url.getPort());
System.out.println("文件路径:" + url.getPath());
System.out.println("文件名:" + url.getFile());
System.out.println("在文件中的相对位置(喵点):" + url.getRef());//注意如果存在锚点,那么查询名返回null,因为#后面全部当做锚点了
System.out.println("获取该url的查询名字:" + url.getQuery());
public final InputStream openStream():返回一个用于从该连接读入的 InputStream。
URL url2 = new URL("http://www.baidu.com");
InputStream input = url.openStream(); //返回一个用于从该连接读入的 InputStream
byte[] data = new byte[1024];
int len;
while((len = input.read(data)) != -1){
String s = new String(data, 0, len, "UTF-8");
System.out.println(s);
} input.close();

URLConnection

URL的方法openStream(),能从网络上读取数据,但是无法给服务器端发送数据,若希望给服务器端发送数据,则需要URLConnection。

它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:

  1. 通过 URL对象调用 openConnection 方法创建URLConnection连接对象。
  2. 处理设置参数和一般请求属性。
  3. 使用 connect 方法建立到远程对象的实际连接。

远程对象变为可用。远程对象的头字段和内容变为可访问

从客户端读取发生给服务端(服务端做处理再返回给客户端)

public class TestServer {

    public static void main(String[] args) throws IOException {

        //1.开启服务,等待客户端连接
ServerSocket server = new ServerSocket(9999);//开启服务器
Socket socket = server.accept(); //接收客户的连接
System.out.println("开启服务,连接成功");
//2.接收客户端发来的消息输入:
InputStream inputStream = socket.getInputStream(); //以字节流接收客户端的信息,通过socket接收
InputStreamReader isr = new InputStreamReader(inputStream); //把字节流转成字符流
BufferedReader br = new BufferedReader(isr);//提高效率加上缓冲流
//3.给客户端返回消息输出:
OutputStream os = socket.getOutputStream(); //输出,通过socket输出
PrintStream ps = new PrintStream(os);
//System.out.println(ps);
//对接收的消息做处理
String line;
while((line = br.readLine()) != null){
StringBuilder s = new StringBuilder(line);
System.out.println("收到消息:" + s.toString());
s.reverse();
ps.println(s);
System.out.println("已做处理:" +
s);
}
ps.close();
os.close();
br.close();
isr.close();
inputStream.close();
socket.close();
server.close(); }

}
public class Testclient {

    public static void main(String[] args) throws UnknownHostException, IOException {

        //1.连接服务器
Socket socket = new Socket("localhost", 9999);
//2.从键盘输入消息
Scanner input = new Scanner(System.in); //输入流inputStream
//3.输出给服务端
OutputStream outputStream = socket.getOutputStream();//以字节流通过socket输出给服务端
PrintStream ps = new PrintStream(outputStream);//按行打印
//4.接收服务端发来的消息
InputStream inputStream = socket.getInputStream(); //从网络中通过socket接收服务端发来的
InputStreamReader isr = new InputStreamReader(inputStream);//把字节流转成字符流
BufferedReader br = new BufferedReader(isr); //用缓存包装
//对键盘输入的信息做处理
while(true){
System.out.println("单词:");
String word = input.next(); //从键盘中接收消息
if("bye".equals(word)){
break;
}
System.out.println("从键盘输入:" + word);
ps.println(word); //给服务器发送单词消息; ps.print(word)用这个发送不出去!!!! String line = br.readLine();
System.out.print("返回的单词是:" + line);
}
inputStream.close();
outputStream.close();
input.close();
socket.close(); }
}

接收多个客户端发来的消息

package com.atguigu.manytcpsendword;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket; public class TestServer { public static void main(String[] args) throws IOException {
//1. 开启服务器
ServerSocket server = new ServerSocket(8080);
//2. 接收n个客户端发来的消息
while(true){
Socket socket = server.accept(); String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip + "接入");//记录接入的ip地址
MyMessage m = new MyMessage(socket); //在构造器中赋值
m.start();
} }
} class MyMessage extends Thread{ private Socket socket; //socket负责收发消息, public MyMessage(Socket socket) {
super();
this.socket = socket;
}
public void run(){ InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintStream ps = null;
try {
//1. 接收客户端发来的消息,从网络中读取-->字节流-字符流 -->
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr); //2. 对接收的消息做处理然后返回给客户端
os = socket.getOutputStream();
ps = new PrintStream(os); String line; while((line = br.readLine()) != null){ //line = br.readLine();
StringBuffer s = new StringBuffer(line);
s.reverse();
ps.println(s);
System.out.println("已处理完毕并返回给客户端" + s);
} } catch (IOException e1) {
e1.printStackTrace();
}
try {
ps.close();
os.close();
br.close();
isr.close();
is.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
//server.close();
} }
package com.atguigu.manytcpsendword;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner; public class TestClient { public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
Scanner input = new Scanner(System.in);
//输出给服务端
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os); //接收服务端消息
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);//把接收的字节转成字节
BufferedReader br = new BufferedReader(isr); //把字节包装下提高效率
while(true){
System.out.println("留言:");
String str = input.next(); if("bye".equalsIgnoreCase(str)){
break;
}
//给服务端发 消息
ps.println(str);
//接收服务端发来的消息
String line = br.readLine();
System.out.println("接收到服务端发来的消息:" + line);
}
br.close();
isr.close();
is.close();
ps.close();
os.close();
input.close();
socket.close(); } }

传输文件

public class Server {

    public static void main(String[] args) throws IOException {
//1.创建服务器
ServerSocket server = new ServerSocket(9999); Socket socket = server.accept(); String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip + "已接入");
//2.从客户端读取数据
DataInputStream dis = new DataInputStream(socket.getInputStream());
String fileName = dis.readUTF(); //先确定输出文件的路径,然后再写入数据
FileOutputStream fos = new FileOutputStream("upload/" + fileName);
//读取内容
byte[] data = new byte[1024];
int len;
while((len = dis.read(data)) != -1){
fos.write(data, 0, len);
}
//3.写完之后给客户端回个信号
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("接收完毕,请客户端查阅"); ps.close();
fos.close();
dis.close();
socket.close();
server.close(); } }
public class Client {

    public static void main(String[] args) throws UnknownHostException, IOException {

        //1.连接服务器
Socket socket = new Socket("localhost", 9999); //2.给服务器上传文件
//一.先输入地址
Scanner input = new Scanner(System.in); System.out.println("文件地址:");
String filePath = input.next();
File file = new File(filePath); //因为它是一个file字符串路径对象,所以要用DataIn。。
String pathName = file.getName(); //二.把文件路径和文件名对象化传给服务端
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(pathName); //对象化文件名后,读取时还要同样的readUTF( ) //三.按照字节读取文件内容
FileInputStream fis = new FileInputStream(file); byte[] data = new byte[1024];
int len;
while((len = fis.read(data)) != -1){ //读取文件内容并写入
dos.write(data, 0, len); }
socket.shutdownOutput(); //要先关闭输出流 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收服务端返回的字符串
String line = br.readLine();
System.out.println("接收服务端返回的结果:" + line);
br.close();
fis.close();
dos.close();
input.close();
socket.close(); }
}

可接收多个客户端发来的文件

package com.atguigu.fileputmany;

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket; public class Server { public static void main(String[] args) throws IOException {
//1.创建服务器
ServerSocket server = new ServerSocket(9999); while(true){
Socket socket = server.accept();
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip + "已接入");
MyFile m = new MyFile(socket);
m.start(); }
}
} class MyFile extends Thread{
private Socket socket; public MyFile(Socket socket) {
super();
this.socket = socket;
} public void run(){
//2.从客户端读取数据
DataInputStream dis = null;
FileOutputStream fos = null;
PrintStream ps = null;
try {
dis = new DataInputStream(socket.getInputStream());
String fileName = dis.readUTF();
//先确定输出文件的路径,然后再写入数据
fos = new FileOutputStream("upload/" + fileName);
//读取内容
byte[] data = new byte[1024];
int len;
while((len = dis.read(data)) != -1){
fos.write(data, 0, len);
}
//3.写完之后给客户端回个信号
ps = new PrintStream(socket.getOutputStream());
ps.println("接收完毕,请客户端查阅"); } catch (IOException e1) {
e1.printStackTrace();
} try {
ps.close();
fos.close();
dis.close();
socket.close();
//server.close();
} catch (IOException e) {
e.printStackTrace();
} } }
package com.atguigu.fileputmany;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; public class Client { public static void main(String[] args) throws UnknownHostException, IOException { //1.连接服务器
Socket socket = new Socket("localhost", 9999); //2.给服务器上传文件
//一.先输入地址
Scanner input = new Scanner(System.in); System.out.println("文件地址:");
String filePath = input.next();
File file = new File(filePath); //因为它是一个file字符串路径对象,所以要用DataIn。。
String pathName = file.getName(); //二.把文件路径和文件名对象化传给服务端
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(pathName); //对象化文件名后,读取时还要同样的readUTF( ) //三.按照字节读取文件内容
FileInputStream fis = new FileInputStream(file); byte[] data = new byte[1024];
int len;
while((len = fis.read(data)) != -1){ //读取文件内容并写入
dos.write(data, 0, len); }
socket.shutdownOutput(); //要先关闭输出流,不然接收不到服务端返回的消息 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); //接收服务端返回的字符串
String line = br.readLine();
System.out.println("接收服务端返回的结果:" + line);
br.close();
fis.close();
dos.close();
input.close();
socket.close();
}
}

用TCP实现多人聊天

package com.atguigu.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList; public class TestServer { public static void main(String[] args) throws IOException {
//1.启动服务器
ServerSocket server = new ServerSocket(9999);
ArrayList<Socket> onLine = new ArrayList<Socket>(); //创建集合装开启的线程; while(true){
Socket socket = server.accept();
System.out.println(socket.getInetAddress().getHostAddress() + "连接成功");
//每连接一个,往里边放一个
onLine.add(socket);
Message m = new Message(socket, onLine);
m.start();
} }
} class Message extends Thread{
private Socket socket;
private ArrayList<Socket> onLine;
private String ip;
public Message(Socket socket, ArrayList<Socket> onLine) {
super();
this.socket = socket;
this.onLine = onLine;
}
public void run(){
ip = socket.getInetAddress().getHostAddress();
sendToOther(ip + "上线了"); //小功能,xx上线了,在receive公共聊天室; BufferedReader br = null;
try {
//接收客户端的消息; 把字节变成字符流并提高效率
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while((line = br.readLine()) != null){
//把消息转发给其他的客户端receive公共聊天室;这里写一个方法
sendToOther(line);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
onLine.remove(socket);
sendToOther(ip + "下线了");
}
}
public void sendToOther(String str){ ArrayList<Socket> offline = new ArrayList<Socket>(); for (Socket socket :onLine) { //遍历的是onLine!!!!
if(!(socket.equals(this.socket))){ //如果不是自己就转发
try{
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(str);
}catch(IOException e){
e.printStackTrace();
offline.add(socket);
}
}
}
for (Socket off : offline) {
offline.remove(off);
}
}
}
package com.atguigu.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; public class TestClient { public static void main(String[] args) throws UnknownHostException, IOException {
//1.连接服务器
Socket socket = new Socket("localhost",9999);
//创建两个线程,一个用来发send消息; 一个用来接收receive消息(作为公共的聊天场所)
Send send = new Send(socket);
Receive receive = new Receive(socket); send.start();
receive.start(); try {
send.join();
receive.setExited(true);
receive.join();
} catch (InterruptedException e) { e.printStackTrace();
}
socket.close(); }
} class Send extends Thread{ private Socket socket; public Send(Socket socket) {
super();
this.socket = socket;
} public void run(){
Scanner input = new Scanner(System.in); //从键盘输入消息 PrintStream ps = null;
try {
ps = new PrintStream(socket.getOutputStream());//将键盘输入的消息发出
while(true){
System.out.println("畅聊:");
String message = input.nextLine();
if("bye".equalsIgnoreCase(message)){
break;
}
ps.println(message); //发送出去;
} } catch (IOException e) {
e.printStackTrace();
} finally{
input.close();
} } } class Receive extends Thread{ private Socket socket;
private boolean exited; public Receive(Socket socket) {
super();
this.socket = socket;
}
public void setExited(boolean exited) {
this.exited = exited;
} public void run(){
BufferedReader br = null;
try {
//字节输入流 -->字符 --> 包装下提高效率
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line;
while((line = br.readLine()) != null && !exited){
System.out.println(line);
} } catch (IOException e) {
e.printStackTrace();
}
}
}

基于UDP多人聊天(使用MulticastSocket实现多点广播)

package com.atguigu.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.Scanner; public class TestMulticastSocket {
static Scanner input = new Scanner(System.in);
static String username; public static void main(String[] args) throws IOException {
//1. 创建Socket
MulticastSocket ms = new MulticastSocket(9999);
InetAddress ip = InetAddress.getByName("230.0.0.1"); ms.joinGroup(ip); //把这个ms添加到广播组中
ms.setLoopbackMode(false); //如果为true是禁止回传; System.out.println("用户名:");
username = input.nextLine(); Send send = new Send(ms, ip);
Receive receive = new Receive(ms); send.start();
receive.start(); try {
send.join();
receive.setExited(true);
receive.join(); } catch (InterruptedException e) {
e.printStackTrace();
}
ms.close(); } static class Send extends Thread{ //静态内部类
private MulticastSocket socket; //类
private InetAddress ip; //类
public Send(MulticastSocket socket, InetAddress ip) {
super();
this.socket = socket;
this.ip = ip;
}
public void run(){
while(true){
System.out.println("输入消息:");
String message = input.nextLine();
if("bye".equalsIgnoreCase(message)){
break;
}
//1.创建数据报DatagramPacket
byte[] data = (username + "说:" + message).getBytes(); //把键盘输入的转成字节数组
DatagramPacket dp = new DatagramPacket(data, data.length, ip, 9999); try {
//2.调用调用MulticastSocket类socket 的send方法将数据报发送出去;
socket.send(dp); } catch (IOException e) {
e.printStackTrace();
} } } }
static class Receive extends Thread{
private MulticastSocket socket;
private boolean exited;
public Receive(MulticastSocket socket) {
super();
this.socket = socket;
}
public void setExited(boolean exited) {
this.exited = exited;
} public void run(){ while(!exited){
//1.建立数据报DatagramPacket
byte[] data = new byte[1024];
DatagramPacket dp = new DatagramPacket(data, data.length);
try {
//2.调用MulticastSocket socket的seceive方法发送数据报;
socket.receive(dp);
//3.拆解数据报
int len = dp.getLength();
System.out.println("本次收到的消息:" + new String(data, 0, len)); } catch (IOException e) {
e.printStackTrace();
}
}
} } }

基于UDP协议的网络编程

   TCP:(Transmission Control Protocol,传输控制协议),面向连接的,可靠的,基于字节流的传输层的网络协议。
   服务器端:ServerSocket和Socket,客户端:Socket
  getInputStream()和getOutputStream()
   UDP:(User Datagram Protocol,用户数据报协议),非面向连接的(无连接的),面向事务的基于数据报的不可靠的传输层的网络协议。

   UDP:快,适用于(是否接收到消息要求不高,但是对速度要求高,必须小的),大小限制在64K

  通信的两端也有Socket:DatagramSocket
   DatagramPacket数据报

1、“发送端”
步骤流程:
1、建立发送端的DatagramSocket,需要指定本端的端口号
2、建立数据包DatagramPacket
 数据
 接收端的IP地址
 接收端的端口号
3、调用DatagramSocket的发送方法
4、关闭DatagramSocket 2、“接收端”
步骤流程:
1、建立接收端的DatagramSocket,需要指定本端的IP地址和端口号
2、建立数据包DatagramPacket
 需要指定装数据的数组
3、调用Socket的接收方法
4、拆封数据
5、关闭Socket
上一篇:Oracle EBS SLA 详解(转)


下一篇:js中数组遍历常用的方法