文章目录
- UDP传输基本数据类型
- UDP传输序列化对象
- UDP传输文件
- UDP模拟在线咨询
- TCP基本使用
- TCP模拟登陆
- TCP文件上传
- 模拟登陆
- 网络编程-聊天室
方法 | 功能 |
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();
}
}