底层任然用的TCP/UDP协议
字节传输
客户端
package com.chedu.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端
* 发送 "hello,server" 给服务端
*/
public class SocketTCP01Client {
public static void main(String[] args) throws IOException {
// 1. 连接服务器(ip,端口)
// 解读:连接本机的9999端口。若连接成功返回socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端返回 socket " + socket);
// 2. 连接上后,生成Socket,通过socket.getOutputSteam()
// 得到 和 server对象关联的输出对象
OutputStream outputStream = socket.getOutputStream();
// 3. 通过输出流,写数据 到数据通道
outputStream.write("hello,server".getBytes());
// 结束标记
socket.shutdownOutput();
// 4 获取socket关联的输入流,读取数据
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int readLen = 0;
while ((readLen=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,readLen));
}
// 5. 关闭流对象和socket,必须关闭
outputStream.close();
inputStream.close();
socket.close();
System.out.println("客户端退出");
}
}
服务端
package com.chedu.socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务端
*
*/
public class SocketTCP01Server {
public static void main(String[] args) throws IOException {
// 1. 在本机的 9999端口监听,等待连接,
// 注意:要求本机9999端口未被占用
// 细节: ServerSocket可以通过accept()返回多个Socket[多个客户端来连接服务器的并发]
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端在9999端口监听,等待连接");
// 2. 当有客服端连接时,程序 阻塞,等待连接
// 如果有客户端连接,则会返回Socket对象,程序继续执行
Socket accept = serverSocket.accept();
System.out.println("socket = " + accept.getClass());
// 3.通过getInputStream读取客户端写入到数据通道的数据
InputStream inputStream = accept.getInputStream();
// 4. IO读取
byte[] aByte = new byte[1024];
int readLen = 0;
while ((readLen=inputStream.read(aByte))!=-1){
System.out.println(new String(aByte,0,readLen));
}
// 5 通过getOutputStream发送数据
OutputStream outputStream = accept.getOutputStream();
outputStream.write("服务端发送的消息".getBytes());
accept.shutdownOutput();
// 6.关闭流
inputStream.close();
outputStream.close();
accept.close();
serverSocket.close();
System.out.println("服务端退出");
}
}
字符传输
客户端
package com.chedu.socket;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* 客户端
*/
public class SocketTCP02Client {
public static void main(String[] args) throws IOException {
// 1. 连接服务器(ip,端口)
// 解读:连接本机的9999端口。若连接成功返回socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端返回 socket " + socket);
// 2. 连接上后,生成Socket,通过socket.getOutputSteam()
// 得到 和 server对象关联的输出对象
OutputStream outputStream = socket.getOutputStream();
// 3. 通过输出流,写数据 到数据通道 new OutputStreamWriter(outputStream)
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("客户端发送信息");
bufferedWriter.newLine(); // 结束
bufferedWriter.flush(); // 刷新,否则不保存
// 4 获取socket关联的输入流,读取数据
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println(s);
// 5. 关闭流对象和socket,必须关闭
bufferedReader.close();
bufferedWriter.close();
socket.close();
System.out.println("客户端退出");
}
}
服务端
package com.chedu.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketTCP02Server {
public static void main(String[] args) throws IOException {
// 1. 在本机的 9999端口监听,等待连接,
// 注意:要求本机9999端口未被占用
// 细节: ServerSocket可以通过accept()返回多个Socket[多个客户端来连接服务器的并发]
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端在9999端口监听,等待连接");
// 2. 当有客服端连接时,程序 阻塞,等待连接
// 如果有客户端连接,则会返回Socket对象,程序继续执行
Socket accept = serverSocket.accept();
System.out.println("socket = " + accept.getClass());
// 3.通过getInputStream读取客户端写入到数据通道的数据
InputStream inputStream = accept.getInputStream();
// 4. IO读取
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println(s);
// 5 通过getOutputStream发送数据
OutputStream outputStream = accept.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("服务端发送的消息");
bufferedWriter.newLine();
bufferedWriter.flush();
// 6.关闭流
bufferedWriter.close();
bufferedReader.close();
accept.close();
serverSocket.close();
System.out.println("服务端退出");
}
}
通过socket从客户端上传图片到服务端
客户端
package com.chedu.upload;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
// 客户端连接服务端
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
String filePath = "e:\\111.webp";
BufferedInputStream bufferedInputStream = new BufferedInputStream(
new FileInputStream(filePath));
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
// 通过socket获取到输出流,将
OutputStream outputStream = socket.getOutputStream();
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
bufferedOutputStream.write(bytes);
bufferedOutputStream.flush();
socket.shutdownOutput();
// 使用StreamUtils方法将InputStream读取到内容转换成字符串
InputStream inputStream = socket.getInputStream();
String s = StreamUtils.inputStreamToString(inputStream);
System.out.println(s);
// 关闭流
inputStream.close();
bufferedOutputStream.close();
bufferedInputStream.close();
socket.close();
}
}
服务端
package com.chedu.upload;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
// 服务端在8888端口监听
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端在8888端口监听");
// 等待连接
Socket accept = serverSocket.accept();
// 读取客户端发送的数据
// 通过socket得到输入流
BufferedInputStream bufferedInputStream = new BufferedInputStream(accept.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
// 将得到的 byte数组,写入指定路径,就得到一个文件
String destFilePath = "src\\222.webp";
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
new FileOutputStream(destFilePath));
bufferedOutputStream.write(bytes);
bufferedOutputStream.close();
// 向客户端发送消息,已保存图片
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(accept.getOutputStream()));
bufferedWriter.write("收到图片");
bufferedWriter.flush(); // 刷新
accept.shutdownOutput(); // 设置结束标记
// 关闭其他资源
bufferedInputStream.close();
accept.close();
serverSocket.close();
}
}
工具类
package com.chedu.upload;
import java.io.*;
public class StreamUtils {
/**
* 功能:将输入流转换成byte[]
*/
public static byte[] streamToByteArray(InputStream is) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();// 创建输出刘对象
byte[] b = new byte[1024]; // 一次读取数据长度
int len;
while ((len = is.read(b))!=-1){ // 循环读取
bos.write(b,0,len); // 把数据读取到数据,写入到bos
}
byte[] array = bos.toByteArray(); // 将bos转换成byte数组
bos.close();
return array;
}
/**
* 将InputStream转换成String
* @param is
* @return
*/
public static String inputStreamToString(InputStream is) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine())!=null){
stringBuilder.append(line + "\r\n");
}
return stringBuilder.toString();
}
}