TCP协议与UDP协议是运输层的两个重要的协议,通过这两个协议来进行两台计算机通信.
套接字
soket是网络驱动层提供应用层的编程的接口和一种数据发送、接受机制,告诉网络驱动层当前应用程序所对应的IP地址和端口号
TCP通信模型
image.pngServerSocket作为服务器端(绑定端口号),监听客户端访问,每一个客户端建立对应Socket
//创建服务器对象
ServerSocket serversocket = new ServerSocket(6010);
//监听客户端访问
Socket socket = serversocket.accept();
Socket作为客户端(IP地址+端口号)
//创建客户端对象
socket = new Socket("192.168.104.163", 6006);
TCPSocket通信过程
TCP通信过程.png客户端,通过Socket对象创建输出字节流
OutputStream outputstream = socket.getoutputStream();
//向服务器端发送信息
OutputStream outputStream = socket.getOutputStream();
//输入信息字节
outputStream.write("我是刘德华".getBytes());
//刷新缓存区域
outputStream.flush();
服务器端,通过Socket对象创建输入字节流
//获取客户端信息,输入流,读入
InputStream inputStream =socket.getInputStream();
byte[] b = new byte[1024];
//读取信息
int length = inputStream.read(b);
//字节信息转换为String
String str = new String(b,0,length)
代码示例
以图片文件上传为例,结合多线程操作.
服务器代码
package com.apesource.demo;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 服务器端最重要的是端口号,监听端口有没有客户端来访问,保存来自客户端的图片
*/
public class ServiceImgetTest {
public static void main(String[] args) {
try(ServerSocket serverSocket = new ServerSocket(8030)) {
// 创建服务器端
System.out.println("服务器已经启动");
// 监听客户端
Socket socket = serverSocket.accept();
System.out.println("客户端已经连接");
Thread thread = new Thread(new ImageloadThread(socket));
thread.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//使用多线程来保存图片
class ImageloadThread implements Runnable {
// 关联Socket
private Socket socket;
public ImageloadThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 创建用来保存图片的目录
File file = new File("E:\\Image\\Test");
// 不存在就创建文件夹
if (!file.exists()) {
file.mkdirs();
}
// 创建用来保存图片的文件
File imageFile = new File(
file.getName() + File.separator + System.currentTimeMillis() + ((int) Math.random() * 10000) + ".jpg");
// 如果文件不在就创建文件
if (!imageFile.exists()) {
imageFile.createNewFile();
}
//读取客户端发来的图片
InputStream inputStream = socket.getInputStream();
//创建字节数组
byte[] data = new byte[1024];
//创建输出流,写入本地磁盘
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(imageFile));
//读操作
int length = -1;
while((length=inputStream.read(data))!= -1) {
//边读边写入磁盘
bos.write(data,0,length);
bos.flush();
}
bos.close();
//向客户端返回成功
OutputStream outputStream = socket.getOutputStream();
outputStream.write("成功了呢".getBytes());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客户端代码
package com.apesource.demo;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class CilentImageTest {
public static void main(String[] args) {
// 本地图片地址
String path = "E:\\我的QQ接受文件\\MobileFile\\IMG_20191118_112813.jpg";
try {
Socket socket = new Socket("192.168.137.1", 8030);
// 向服务器发送数据
OutputStream outputStream = socket.getOutputStream();
// 获取本地图图片信息
BufferedInputStream bfs = new BufferedInputStream(new FileInputStream(path));
byte[] data = new byte[1024];
int length = -1;
// 写出到服务器
while ((length = bfs.read(data)) != -1) {
outputStream.write(data);
}
// 标记上传完成
socket.shutdownOutput();
// 获取服务器的上传成功
InputStream inputStream = socket.getInputStream();
data = new byte[1024];
int x = inputStream.read(data);
String str = new String(data, 0, x);
System.out.println(str);
bfs.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
基于UDP协议的数据传送
无需建立连接,一次发送
DatagramSocket类创建套接字,无明显的客户端和服务端之分.接受方就是服务端,发送方就是客户端.
服务器端往往需要监听端口号,客户端往往要知道发送的IP地址和端口号
DatagramPacket类,将数据打包并发送
服务端往往调用recive()方法,客户端往往使用send方法.
- 服务端
创建套接字,绑定端口,创建空的数据包
//绑定端口号
DatagramSocket datagramSocket = new DatagramSocket(8020);
byte[] data = new byte[1024];
// 创建空的数据包,构造方法字节数组,字节长度
DatagramPacket reciveDatagramPacket = new DatagramPacket(data, data.length);
接受数据
datagramSocket.receive(reciveDatagramPacket );
解析数据包信息
// 1获取发送的地址
InetAddress sendinetAddress = reciveDatagramPacket.getAddress();
// 2获取数据
byte[] datax = reciveDatagramPacket.getData();
// 3获取长度
int length = reciveDatagramPacket.getLength();
//将字节数组转化为String
String str = new String(datax,0,length)
- 客户端
同样要创建DatagramSocket
DatagramSocket datagramSocket = new DatagramSocket()
数据打包发送,数据内容(字节数组),数据长度,服务端地址,端口号
//将发送的数据,发送的地址,发送的端口号,全部打包到DatagramPacket数据包
DatagramPacket sendDatagramPacket = new DatagramPacket(data, data.length,sendInetAddress,8020);
发送数据
//使用DatagramSocket发送数据包DatagramPacket
datagramSocket.send(sendDatagramPacket);
Java爬虫示例(多线程)
package com.apesource.demoURL;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class URLDemo2 {
public static void main(String[] args) {
try {
// 获取网页的URL
URL webURL = new URL("https://book.douban.com/");
// 获取连接
HttpsURLConnection httpURLConnection = (HttpsURLConnection) webURL.openConnection();
// 读取网页字符信息
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
// 循环读取
String line = null;
while ((line = bufferedReader.readLine()) != null) {
int suffix = line.indexOf(".jpg");
if (line.indexOf("<img") > 0 && suffix > 0) {
// 截取图片的src
String src = line.substring(line.indexOf("https"), suffix + 4);
System.out.println(src);
// 多线程下载图片
// 创建线程
Thread thread = new Thread(new LoadImageThread(src));
thread.start();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class LoadImageThread implements Runnable {
private String src;
public LoadImageThread(String src) {
this.src = src;
}
@Override
public void run() {
try {
// 创建图片的URL
URL imgURL = new URL(src);
// 获取连接
HttpsURLConnection connection = (HttpsURLConnection) imgURL.openConnection();
// 读取图片
BufferedInputStream bis = new BufferedInputStream(connection.getInputStream());
// 获取文件名
String name = this.src.substring(this.src.lastIndexOf("/") + 1);
// 写入本地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\Image\\Test" + name));
byte[] dta = new byte[1024];
int len = -1;
while ((len = bis.read(dta)) != -1) {
bos.write(dta, 0, dta.length);
}
bos.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
网友评论