文章目录



方法

功能

InetAddress

封装计算机的IP地址和DNS(没有端口信息)。 常用方法:getLocalHost()、getByName()、getAllByName()、 getAddress()、getHostName()

InetSocketAddres s

包含IP和端口信息,常用于Socket通信。此类实现IP套接字地址(IP地址+端口号),不依赖任何协议。 常用方法:getHostName()、getAddress()

URL

类 URL 代表一个统一资源定位符,它是指向互联网“资源” 的指针。资源可以是简单的文件或目录,也可以是对更为复杂 的对象的引用,例如对数据库或搜索引擎的查询。 常用方法: getDefaultPort()、getFile()、getHost()、 getPath()、getPort()、getProtocol()、getQuery()、 getRef()

认识TCP和UDP

TCP协议和UDP协议是传输层的两种协议。Socket是传输层供给应用层的编程接口,所以Socket编程就分为TCP编程和UDP编程两类。

1). TCP是面向连接的,传输数据安全,稳定,效率相对较低。

2). UDP是面向无连接的,传输数据不安全,效率较高。

TCP(Transfer Control Protocol)是面向连接的,所谓面向连接,就是当计算机双方通信时必需经过先建立连接,然后传送数据,最后拆除连接三个过程。

TCP在建立连接时又分三步:

第一步,是请求端(客户端)发送一个包含SYN即同步(Synchronize)标志的TCP报文,SYN同步报文会指明客户端使用的端口以及TCP连接的初始序号。

第二步,服务器在收到客户端的SYN报文后,将返回一个SYN+ACK的报文,表示客户端的请求被接受,同时TCP序号被加一,ACK即确认(Acknowledgement)。

第三步,客户端也返回一个确认报文ACK给服务器端,同样TCP序列号被加一,到此一个TCP连接完成。然后才开始通信的第二步:数据处理。

这三步也叫TCP的三次握手(Three-way Handshake)。

基于TCP协议可以建立稳定连接的点对点的通信。这种通信方式实时、快速、安全性高,但是很占用系统的资源。

在网络传输方式上,还有另一种基于UDP协议的通信方式,称为数据报通信方式。在这种方式中,每个数据发送单元被统一封装成数据报包的方式,发送方将数据报包发送到网络中,数据报包在网络中去寻找它的目的地。

​java网络编程中,java.net包提供了网络功能​

InetAddress

作用: 封装计算机的IP地址和DNS(没有端口信息)。

特点: 这个类没有构造方法。如果要得到对象,只能通过静态方法:​​getLocalHost()、getByName()、 getAllByName()、 getAddress()、getHostName()。​

使用getLocalHost方法创建InetAddress对象

import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test1 {
public static void main(String[] args) throws UnknownHostException {
InetAddress addr = InetAddress.getLocalHost();
//返回IP地址:192.168.1.66
System.out.println(addr.getHostAddress());
//输出计算机名:sweetheart
System.out.println(addr.getHostName());
}
}

根据域名得到InetAddress对象

import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test2 {
public static void main(String[] args) throws UnknownHostException {
InetAddress addr = InetAddress.getByName("www.baidu.com");
// 返回 baidu服务器的IP:xxx.xxx.xxx.xxx
System.out.println(addr.getHostAddress());
// 输出:www.baidu.com
System.out.println(addr.getHostName());
}
}

根据IP得到InetAddress对象

import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test3 {
public static void main(String[] args) throws UnknownHostException {
InetAddress addr = InetAddress.getByName("xxx.xxx.xxx.xxx");
// 返回baidu服务器的IP:xxx.xxx.xxx.xxx
System.out.println(addr.getHostAddress());
/*
* 输出ip而不是域名。如果这个IP地址不存在或DNS服务器不允许进行IP地址
* 和域名的映射,getHostName方法就直接返回这个IP地址。
*/
System.out.println(addr.getHostName());
}
}

InetSocketAddress

作用: 包含IP和端口信息,常用于Socket通信。此类实现 IP 套接字地址(IP 地址 + 端口号),不依赖任何协议。

import java.net.InetSocketAddress;
public class Test4 {
public static void main(String[] args) {
InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 9000);
System.out.println(socketAddress.getHostName());
System.out.println(socketAddress2.getAddress());
}
}

URL类

IP地址唯一标识了Internet上的计算机,而URL则标识了这些计算机上的资源。类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

为了方便程序员编程,JDK中提供了URL类,该类的全名是java.net.URL,有了这样一个类,就可以使用它的各种方法来对URL对象进行分割、合并等处理。

URL类的使用

import java.net.MalformedURLException;
import java.net.URL;
public class Test5 {
public static void main(String[] args) throws MalformedURLException {
URL u = new URL("http://www.google.cn:80/webhp#aa?canhu=33");
System.out.println("获取与此url关联的协议的默认端口:" + u.getDefaultPort());
System.out.println("getFile:" + u.getFile()); // 端口号后面的内容
System.out.println("主机名:" + u.getHost()); // www.google.cn
System.out.println("路径:" + u.getPath()); // 端口号后,参数前的内容
// 如果www.google.cn:80则返回80.否则返回-1
System.out.println("端口:" + u.getPort());
System.out.println("协议:" + u.getProtocol());
System.out.println("参数部分:" + u.getQuery());
System.out.println("锚点:" + u.getRef());

URL u1 = new URL("http://www.abc.com/aa/");
URL u2 = new URL(u, "2.html"); // 相对路径构建url对象
System.out.println(u2.toString()); // http://www.abc.com/aa/2.html
}
}

简易的网络爬虫

package cn.whb.it;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

/**
* 网络爬虫
* @author sweetheart
*
*/
public class SpiderTest01 {

public static void main(String[] args) throws Exception {
// 获取URL
URL url = new URL("https://www.jd.com");
// 下载资源
InputStream is = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
String msg = null;
while((msg=br.readLine())!=null) {
System.out.println(msg);
}

br.close();
}

}
-----------------------------------------------------------

package cn.whb.it;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
* 网络爬虫 + 模拟浏览器
* @author sweetheart
*
*/
public class SpiderTest02 {

public static void main(String[] args) throws Exception {
// 获取URL
URL url = new URL("https://www.dianping.com");
// 下载资源(打开连接)
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("User-Agent","Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
String msg = null;
while((msg=br.readLine())!=null) {
System.out.println(msg);
}

br.close();
}

}

UDP基本使用

接收端

package cn.whb.it;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
* 接收端 基本流程
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 封装成DatagramPacket 包裹
* 3.阻塞式接收包裹receive(DatagramPacket p)
* 4.分析数据
* byte[] getData()
* getLength()
* 5.释放资源
* @author sweetheart
*
*/
public class UDPServer {

public static void main(String[] args) throws Exception {
System.out.println("接收方启动中.....");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(9999);
// 2.准备容器 封装成DatagramPacket 包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3.阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); // 阻塞
// 4.分析数据
// byte[] getData()
// getLength()
byte[] datas = packet.getData();
int len = packet.getLength();
System.out.println(new String(datas,0,len));
// 5.释放资源
server.close();
}
}

发送端

package cn.whb.it;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
* 发送端 基本流程
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 必须转成字节数组
* 3.封装成DatagramPacket 包裹,需要指定目的地
* 4.发送包裹send(DatagramPacket p)
* 5.释放资源
* @author sweetheart
*
*/
public class UDPClient {

public static void main(String[] args) throws Exception {
System.out.println("发送方启动中.......");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(8888);
// 2.准备容器 必须转成字节数组
String data = "Hello World";
byte[] datas = data.getBytes();
// 3.封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("127.0.0.1",9999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}

UDP传输基本数据类型

package cn.whb.it;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
* 发送基本数据类型(需要转为字节数组发送)
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 必须转成字节数组
* 3.封装成DatagramPacket 包裹,需要指定目的地
* 4.发送包裹send(DatagramPacket p)
* 5.释放资源
* @author sweetheart
*
*/
public class UDPTypeClient {

public static void main(String[] args) throws Exception {
System.out.println("发送方启动中.......");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(8888);
// 2.准备容器 必须转成字节数组
// 创建流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);

// 操作
dos.writeUTF("Hello World");
dos.writeInt(18);
dos.writeBoolean(true);

byte[] datas = baos.toByteArray();

// 3.封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("127.0.0.1",9999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}
-------------------------------------------------------------------

package cn.whb.it;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
* 接收基本数据类型
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 封装成DatagramPacket 包裹
* 3.阻塞式接收包裹receive(DatagramPacket p)
* 4.分析数据
* byte[] getData()
* getLength()
* 5.释放资源
* @author sweetheart
*
*/
public class UDPTypeServer {

public static void main(String[] args) throws Exception {
System.out.println("接收方启动中.....");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(9999);
// 2.准备容器 封装成DatagramPacket 包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3.阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); // 阻塞
// 4.分析数据
// byte[] getData()
byte[] datas = packet.getData();
// 创建流并读取数据
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(datas));

String msg = dis.readUTF();
int i = dis.readInt();
boolean flag = dis.readBoolean();

System.out.println("msg:"+msg+" i:"+i+" flag:"+flag);

// 5.释放资源
server.close();
}
}

UDP传输序列化对象

package cn.whb.it;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;

/**
* 接收并反系列化对象
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 封装成DatagramPacket 包裹
* 3.阻塞式接收包裹receive(DatagramPacket p)
* 4.分析数据
* byte[] getData()
* getLength()
* 5.释放资源
* @author sweetheart
*
*/
public class UDPObjectServer {

public static void main(String[] args) throws Exception {
System.out.println("接收方启动中.....");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(9999);
// 2.准备容器 封装成DatagramPacket 包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3.阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); // 阻塞
// 4.分析数据
// byte[] getData()
byte[] datas = packet.getData();

// 读取 --> 反系列化
ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));

// 顺序与写出一致
String msg = ois.readUTF();
int age = ois.readInt();
boolean flag = ois.readBoolean();
char ch = ois.readChar();
System.out.println(flag);

// 对象的数据还原
Object str = ois.readObject();
Object date = ois.readObject();
Object employee = ois.readObject();

if(str instanceof String) {
String strObj = (String)str;
System.out.println(strObj);
}

if(date instanceof Date) {
Date dateObj = (Date)date;
System.out.println(date);
}

if(employee instanceof Employee) {
Employee e = (Employee)employee;
System.out.println(e.getName()+"-->"+e.getSalary());
}

// 5.释放资源
server.close();
}
}
--------------------------------------------------

package cn.whb.it;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Date;

/**
* 发送序列化对象
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 必须转成字节数组
* 3.封装成DatagramPacket 包裹,需要指定目的地
* 4.发送包裹send(DatagramPacket p)
* 5.释放资源
* @author sweetheart
*
*/
public class UDPObjectClient {

public static void main(String[] args) throws Exception {
System.out.println("发送方启动中.......");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(8888);
// 2.准备容器 必须转成字节数组

// 创建流并写出序列化对象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(baos));

// 操作数据类型 + 数据
oos.writeUTF("编码");
oos.writeInt(18);
oos.writeBoolean(false);
oos.writeChar('a');

// 对象
oos.writeObject("string");
oos.writeObject(new Date());
Employee emp = new Employee("xiaobo",123132);
oos.writeObject(emp);
oos.flush();

byte[] datas = baos.toByteArray();

// 3.封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("127.0.0.1",9999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}
---------------------------------------------------------

package cn.whb.it;
class Employee implements java.io.Serializable{
private transient String name; // 该数据不需要序列化
private double salary;

public Employee() {
// TODO Auto-generated constructor stub
}

public Employee(String name, double salary) {
super();
this.name = name;
this.salary = salary;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getSalary() {
return salary;
}

public void setSalary(double salary) {
this.salary = salary;
}
}

UDP传输文件

package cn.whb.it;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
* 接收图片
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 封装成DatagramPacket 包裹
* 3.阻塞式接收包裹receive(DatagramPacket p)
* 4.分析数据
* byte[] getData()
* getLength()
* 5.释放资源
* @author sweetheart
*
*/
public class UDPFileServer {

public static void main(String[] args) throws Exception {
System.out.println("接收方启动中.....");
//1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket server = new DatagramSocket(9999);
// 2.准备容器 封装成DatagramPacket 包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3.阻塞式接收包裹receive(DatagramPacket p)
server.receive(packet); // 阻塞
// 4.分析数据
// byte[] getData()
// getLength()
byte[] datas = packet.getData();
IOUtils.byteArrayToFile(datas, "./a.png");
// 5.释放资源
server.close();
}
}
--------------------------------------------------

package cn.whb.it;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
* 发送图片
* 1.使用DatagramSocket 指定端口 创建接收端
* 2.准备容器 必须转成字节数组
* 3.封装成DatagramPacket 包裹,需要指定目的地
* 4.发送包裹send(DatagramPacket p)
* 5.释放资源
* @author sweetheart
*
*/
public class UDPFileClient {

public static void main(String[] args) throws Exception {
System.out.println("发送方启动中.......");
// 1.使用DatagramSocket 指定端口 创建接收端
DatagramSocket client = new DatagramSocket(8888);
// 2.准备容器 必须转成字节数组

byte[] datas = IOUtils.fileToByteArray("./123.png");

// 3.封装成DatagramPacket 包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("127.0.0.1",9999));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
// 5.释放资源
client.close();
}
}
---------------------------------------------------

package cn.whb.it;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOUtils {

/**
* 1. 图片读取到字节数组
* 1) 图片到程序 FileInputStream
* 2) 程序到字节数组 ByteArrayOutput
*/

public static byte[] fileToByteArray(String filepath) {

// 1.创建源与目的地
File src = new File(filepath);

// 2.选择流
InputStream is = null;
ByteArrayOutputStream baos = null;

try {
is = new FileInputStream(src);
baos = new ByteArrayOutputStream();

// 3.操作(分段读取)
byte[] flush = new byte[1024*10];
int len = -1;
while((len=is.read(flush))!=-1) {
baos.write(flush,0,len); // 写到字节数组
}

baos.flush();
return baos.toByteArray();

} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {

try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}

/**
* 2. 字节数组写到图片
* 1) 字节数组到程序 ByteArrayInputStream
* 2) 程序到文件 FileOutputStream
*/

public static void byteArrayToFile(byte[] src, String filepath) {

// 1.创建源
File dest = new File(filepath);

// 2.选择流
InputStream is = null;
OutputStream os = null;

try {

is = new ByteArrayInputStream(src);
os = new FileOutputStream(dest,true);

// 操作(分段读取)
byte[] flush = new byte[5]; // 缓冲容器
int len = -1;
while((len=is.read(flush))!=-1) {
os.write(flush,0,len); // 写出到文件
}

os.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {

try {
if(null!=os) {
os.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

UDP模拟在线咨询

package cn.whb.it;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

/**
* 发送端:使用面向对象封装
* @author sweetheart
*
*/
public class TalkSend implements Runnable {
private DatagramSocket client;
BufferedReader br;
private String toIP;
private int toPort;

public TalkSend(int port,String toIP,int toPort) {
this.toIP = toIP;
this.toPort = toPort;

try {
client = new DatagramSocket(port);
br = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
}

public void run() {

while(true) {
String data;
try {
data = br.readLine();
byte[] datas = data.getBytes();
// 3.封装成DatagramPacket包裹,需要指定目的地
DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));
// 4.发送包裹send(DatagramPacket p)
client.send(packet);
if(data.equals("bye")) {
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
client.close();
}

}
----------------------------------------------------------------------------------

package cn.whb.it;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
* 接收端:使用面向对象封装
* @author sweetheart
*
*/
public class TalkReceive implements Runnable{

private DatagramSocket server;
private String name;

public TalkReceive(int port,String name) {
this.name = name;

System.out.println(name+"加入聊天");

try {
server = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}

public void run() {
while (true) {
// 2.准备容器 封装成DatagramPacket包裹
byte[] container = new byte[1024*60];
DatagramPacket packet = new DatagramPacket(container,0,container.length);
// 3.阻塞式接收包裹receive(DatagramPacket p)
try {
server.receive(packet);// 阻塞式
// 4.分析数据
// byte[] getData()
// getLength()
byte[] datas = packet.getData();
int len = packet.getLength();
String ss = new String(datas,0,len);

System.out.println(name+"说:"+ss);

if(ss.equals("bye")) {
break;
}
} catch (IOException e) {
e.printStackTrace();
}

}

// 5.释放资源
server.close();
}

}
----------------------------------------------------------------

package cn.whb.it;
/**
* 加入多线程实现双向交流 模拟在线咨询
* @author sweetheart
*
*/
public class TalkStudent {

public static void main(String[] args) {

new Thread(new TalkSend(7777, "localhost", 9999)).start();
new Thread(new TalkReceive(8888,"老师")).start();
}

}
-----------------------------------------------------------------

package cn.whb.it;
/**
* 加入多线程实现双向交流 模拟在线咨询
* @author sweetheart
*
*/
public class TalkTeacher {

public static void main(String[] args) {

new Thread(new TalkReceive(9999,"学生")).start();

new Thread(new TalkSend(5555, "localhost", 8888)).start();
}
}

TCP基本使用

package cn.whb.it2;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
* 创建客户端
* 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
* 2. 操作: 输入输出流操作
* 3. 释放资源
* @author sweetheart
*
*/
public class Client {

public static void main(String[] args) throws UnknownHostException, IOException {
// 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
System.out.println("----client-----");
Socket client = new Socket("localhost",8888);
// 2. 操作: 输入输出流操作
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
String data = "Hello";
dos.writeUTF(data);
dos.flush();
// 3. 释放资源
dos.close();
client.close();
}

}
-----------------------------------------------------------

package cn.whb.it2;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 创建服务器
* 1. 指定端口 使用ServerSocket创建服务器
* 2. 阻塞式等待连接 accept
* 3. 操作: 输入输出流操作
* 4. 释放资源
* @author sweetheart
*
*/
public class Server {

public static void main(String[] args) throws IOException {
System.out.println("----server-----");
// 1. 指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(8888);
// 2. 阻塞式等待连接 accept
Socket client = server.accept();
System.out.println("一个客户端建立了连接");
// 3. 操作: 输入输出流操作
DataInputStream dis = new DataInputStream(client.getInputStream());
String data = dis.readUTF();
System.out.println(data);
// 4. 释放资源
dis.close();
client.close();
server.close();
}

}

TCP模拟登陆

package cn.whb.it2;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 模拟登陆
* 1. 指定端口 使用ServerSocket创建服务器
* 2. 阻塞式等待连接 accept
* 3. 操作: 输入输出流操作
* 4. 释放资源
* @author sweetheart
*
*/
public class LoginServer {

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

System.out.println("----server-----");
// 1. 指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(9999);

// 2. 阻塞式等待连接 accept
Socket client = server.accept();
System.out.println("一个客户端建立了连接");

// 3. 操作: 输入输出流操作
DataInputStream dis = new DataInputStream(client.getInputStream());
String data = dis.readUTF();
String[] dataArray = data.split("&");
String uname = "";
String upwd = "";

for(String info:dataArray) {

String[] userinfo = info.split("=");
if(userinfo[0].equals("uname")) {
System.out.println("你的用户名为:"+userinfo[1]);
uname = userinfo[1];
}else if(userinfo[0].equals("upwd")) {
System.out.println("你的密码为:"+userinfo[1]);
upwd = userinfo[1];
}
}

DataOutputStream dos = new DataOutputStream(client.getOutputStream());

if(uname.equals("123")&&upwd.equals("123")) {
dos.writeUTF("登陆成功 欢迎回来");
}else {
dos.writeUTF("用户名或密码错误");
}

dos.flush();

// 4. 释放资源
dis.close();
dos.close();
client.close();
server.close();
}

}
--------------------------------------------------

package cn.whb.it2;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/**
* 模拟登陆
* 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
* 2. 操作: 输入输出流操作
* 3. 释放资源
* @author sweetheart
*
*/
public class LoginClient {

public static void main(String[] args) throws UnknownHostException, IOException {
// 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
System.out.println("----client-----");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入用户名:");
String uname = br.readLine();
System.out.print("请输入密码:");
String upwd = br.readLine();

Socket client = new Socket("localhost",9999);
// 2. 操作: 输入输出流操作
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("uname="+uname+"&"+"upwd="+upwd);
dos.flush();

// 读取反馈信息
DataInputStream dis = new DataInputStream(client.getInputStream());
String data = dis.readUTF();
System.out.println(data);

// 3. 释放资源
dis.close();
dos.close();
client.close();
}

}

TCP文件上传

package cn.whb.it2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 保存文件
* 1. 指定端口 使用ServerSocket创建服务器
* 2. 阻塞式等待连接 accept
* 3. 操作: 输入输出流操作
* 4. 释放资源
* @author sweetheart
*
*/
public class FileServer {

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

System.out.println("----server-----");

// 1. 指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(7788);

// 2. 阻塞式等待连接 accept
Socket client = server.accept();
System.out.println("一个客户端建立了连接");

// 3. 操作: 输入输出流操作
InputStream is = new BufferedInputStream(client.getInputStream());
OutputStream os = new BufferedOutputStream(new FileOutputStream("./1.png"));
byte[] data = new byte[1024];
int len = -1;

while((len=is.read(data))!=-1) {
os.write(data,0,len);
}
os.flush();

// 4. 释放资源
os.close();
is.close();
client.close();
server.close();
}

}
-------------------------------------------------------

package cn.whb.it2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/**
* 上传文件
* 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
* 2. 操作: 输入输出流操作
* 3. 释放资源
* @author sweetheart
*
*/
public class FileClient {

public static void main(String[] args) throws UnknownHostException, IOException {
// 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
System.out.println("----client-----");

Socket client = new Socket("localhost",7788);

// 2. 操作: 输入输出流操作(文件拷贝)
InputStream is = new BufferedInputStream(new FileInputStream("./123.png"));
OutputStream os = new BufferedOutputStream(client.getOutputStream());

byte[] data = new byte[1024];
int len = -1;
// 读取反馈信息
while((len=is.read(data))!=-1) {
os.write(data,0,len);
}
os.flush();

// 3. 释放资源
is.close();
os.close();
client.close();
}

}

模拟登陆

package cn.whb.it2;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

/**
* 模拟登陆
* 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
* 2. 操作: 输入输出流操作
* 3. 释放资源
* @author sweetheart
*
*/
public class LoginClient {

public static void main(String[] args) throws UnknownHostException, IOException {
// 1. 建立连接: 使用Socket创建客户端 + 服务的地址和端口
System.out.println("----client-----");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入用户名:");
String uname = br.readLine();
System.out.print("请输入密码:");
String upwd = br.readLine();

Socket client = new Socket("localhost",9999);
// 2. 操作: 输入输出流操作
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("uname="+uname+"&"+"upwd="+upwd);
dos.flush();

// 读取反馈信息
DataInputStream dis = new DataInputStream(client.getInputStream());
String data = dis.readUTF();
System.out.println(data);

// 3. 释放资源
dis.close();
dos.close();
client.close();
}

}
-------------------------------------------------------------

package cn.whb.it2;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 模拟登陆
* 1. 指定端口 使用ServerSocket创建服务器
* 2. 阻塞式等待连接 accept
* 3. 操作: 输入输出流操作
* 4. 释放资源
* @author sweetheart
*
*/
public class LoginServer {

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

System.out.println("----server-----");
// 1. 指定端口 使用ServerSocket创建服务器
ServerSocket server = new ServerSocket(9999);

// 2. 阻塞式等待连接 accept
Socket client = server.accept();
System.out.println("一个客户端建立了连接");

// 3. 操作: 输入输出流操作
DataInputStream dis = new DataInputStream(client.getInputStream());
String data = dis.readUTF();
String[] dataArray = data.split("&");
String uname = "";
String upwd = "";

for(String info:dataArray) {

String[] userinfo = info.split("=");
if(userinfo[0].equals("uname")) {
System.out.println("你的用户名为:"+userinfo[1]);
uname = userinfo[1];
}else if(userinfo[0].equals("upwd")) {
System.out.println("你的密码为:"+userinfo[1]);
upwd = userinfo[1];
}
}

DataOutputStream dos = new DataOutputStream(client.getOutputStream());

if(uname.equals("123")&&upwd.equals("123")) {
dos.writeUTF("登陆成功 欢迎回来");
}else {
dos.writeUTF("用户名或密码错误");
}

dos.flush();

// 4. 释放资源
dis.close();
dos.close();
client.close();
server.close();
}

}

网络编程-聊天室

Receive

package cn.whb.it4;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;

/**
* 使用多线程封装: 接收端
* @author sweetheart
*
*/
public class Receive implements Runnable{

private Socket client;
private DataInputStream dis;
private boolean isRunning;

public Receive(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
isRunning = true;
} catch (IOException e) {
System.out.println("----Rece------");
release();
}
}

public void run() {

while(isRunning) {
String msg = receive();
if(!msg.equals("")) {
System.out.println(msg);
}
}

}

private String receive() {
String msg = "";

try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("-----receive----");
release();
}
return msg;
}


// 释放资源
private void release() {
this.isRunning = false;
MyUtils.close(dis,client);
}
}

Send

package cn.whb.it4;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
* 使用多线程封装: 发送端
* @author sweetheart
*
*/

public class Send implements Runnable{

private BufferedReader br;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;

public Send(Socket client,String name) {
this.client = client;
this.name = name;
br = new BufferedReader(new InputStreamReader(System.in));

try {
dos = new DataOutputStream(client.getOutputStream());
send(name);
isRunning = true;
} catch (IOException e) {
System.out.println("-------constru-------");
this.release();
}
}


public void run() {

while(isRunning) {

String msg = getStrFromConsole();
if(!msg.equals("")) {
send(msg);
}
}
}

private void send(String msg) {
try {
dos.writeUTF(msg);
} catch (IOException e) {
System.out.println("-----send-----");
release();
}
}

private String getStrFromConsole() {
try {
return br.readLine();
} catch (IOException e) {
System.out.println("--read---");
e.printStackTrace();
}
return "";
}

// 释放资源
private void release() {
this.isRunning = false;
MyUtils.close(dos,client);
}
}

Chat

package cn.whb.it4;

import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;

/**
* 在线聊天室: 服务端
* 目标: 加入容器实现群聊 | 私聊
* @author sweetheart
*
*/
public class Chat {

// private List<Channel> all = new ArrayList<>();
// 多线程操作,建议使用这个容器,防止并发问题
private static CopyOnWriteArrayList<Channel> all = new CopyOnWriteArrayList<>();

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

System.out.println("-----Server-------");
// 1. 指定端口 使用ServerSocker创建服务器
ServerSocket server = new ServerSocket(9999);


// 2. 阻塞式等待连接accept
while(true) {
Socket client = server.accept();
System.out.println("一个客户端建立了连接");
Channel c = new Channel(client);
all.add(c); // 管理所有的成员
new Thread(c).start();
}
}

// 一个客户代表一个Channel
static class Channel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private Socket client;
private boolean isRunning;
private String name;

public void run() {
while(isRunning) {
String msg = receive();
if(!msg.equals("")) {
sendOthers(msg,false);
}
}
}

public Channel(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
// 获取名称
this.name = receive();
// 欢迎
this.send("欢迎你的到来");
sendOthers(this.name+"加入了聊天室",true);

isRunning = true;
} catch (IOException e) {

System.out.println("-----constr--------");
release();
}
}

// 接收消息
private String receive() {
String msg = "";

try {
msg = dis.readUTF();
} catch (IOException e) {
System.out.println("-----receive----");
release();
}
return msg;
}

// 发送消息
private void send(String msg) {
try {
dos.writeUTF(msg);
} catch (IOException e) {
System.out.println("-----send-----");
release();
}
}

/**
* 群聊: 获取自己的消息发给其他人
* 私聊数据格式: @xx: msg
* @param msg
*/
private void sendOthers(String msg,boolean isSys) {

boolean isPrivate = msg.startsWith("@");

if(isPrivate) {

int ind = msg.indexOf(":");
String usr = msg.substring(1,ind);
msg = msg.substring(ind+1);

for(Channel other:all) {
if(other.name.equals(usr)) {
other.send(this.name+"悄悄对你说:"+msg);
break;
}
}

}else {

for(Channel other:all) {
if(other==this) {
continue;
}
if(!isSys) {
other.send(this.name+"对所有人说:"+msg);
}else {
other.send(msg);
}
}
}
}

// 释放资源
private void release() {
this.isRunning = false;
MyUtils.close(dis,dos,client);
all.remove(this);
sendOthers(this.name+"离开了群聊", true);
}
}
}

class MyUtils{

public static void close(Closeable... targets) {
for(Closeable target:targets) {
try {
if(null!=target) {
target.close();
}
}catch(Exception e) {

}
}
}
}

Client

package cn.whb.it4;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
* 在线聊天室: 客户端
* 目标: 加入容器实现群聊 | 私聊
* @author sweetheart
*
*/
public class Client {

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

System.out.println("---client---");

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.println("请输入用户名:");
String name = br.readLine();

// 1.建立连接: 使用Socket创建客户端 + 服务的地址和端口
Socket client = new Socket("localhost",9999);

// 2.客户端发送消息
new Thread(new Send(client,name)).start();
new Thread(new Receive(client)).start();

}
}