简介
socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据。网络通信其实就是socket通信,通信的两端都要有socket,一般发起通信的一端叫客户端,等待通信的一端属于服务端。
原理
1、服务端新建一个socket,绑定地址和开启端口的监听,此时服务端进入阻塞状态,等待客户端的连接
2、客户端新建一个socket,实例化socket时关联服务端的ip,端口,连接服务端
3、服务端和客户端建立连接后就可以收/发数据
4、关闭连接
案例1
客户端给服务端发送消息
服务端
package com.tk.socket.demo01;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author taoke
* @desc socket服务端,接收客户端发送的消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
try {
System.out.println("服务端已启动~~~~");
//开启本地端口9999的监听
serverSocket = new ServerSocket(9999);
阻塞,等待客户端的连接
socket = serverSocket.accept();
System.out.println("客户端连接成功~~~~");
//从通道获取输入流
inputStream = socket.getInputStream();
int len;
byte[] b = new byte[1024];
//以字节流的形式读取客户端发送的消息
while ((len = inputStream.read(b)) != -1) {
System.out.println(new String(b, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出服务端~~~~");
//释放资源
try {
if (inputStream != null) {
inputStream.close();
}
if (socket != null) {
socket.close();
}
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
package com.tk.socket.demo01;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author taoke
* @desc socket客户端,给服务端发送消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
//连接服务端
socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("连接服务器成功~~~~~~");
//从通道获取输出流
outputStream = socket.getOutputStream();
//给服务端发送消息
outputStream.write("hello server,i am client".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出客户端~~~~");
//释放资源
try {
if (outputStream != null) {
outputStream.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果
1.服务端启动,进入阻塞状态,等待客户端的连接
2、客户端启动,连接服务端,给客户端发送消息
3、服务端成功接收到消息,退出程序
案例2
客户端给服务端发送消息,服务端收到消息后回复客户端
服务端
package com.tk.socket.demo02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author taoke
* @desc socket服务端,客户端给服务端发送消息,服务端收到消息后回复客户端
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
System.out.println("服务端已启动~~~~");
serverSocket = new ServerSocket(9999);
socket = serverSocket.accept();
System.out.println("客户端连接成功~~~~");
inputStream = socket.getInputStream();
int len;
byte[] b = new byte[1024];
while ((len = inputStream.read(b)) != -1) {
System.out.println(new String(b, 0, len));
}
outputStream = socket.getOutputStream();
outputStream.write("hello client,i am server".getBytes());
//设置结束写入标记
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出服务端~~~~");
try {
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
if (socket != null) {
socket.close();
}
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
package com.tk.socket.demo02;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author taoke
* @desc socket客户端,客户端给服务端发送消息,服务端收到消息后回复客户端
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
InputStream inputStream = null;
try {
socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("连接服务器成功~~~~~~");
outputStream = socket.getOutputStream();
outputStream.write("hello server,i am client".getBytes());
//设置结束写入标记
socket.shutdownOutput();
inputStream = socket.getInputStream();
int len;
byte[] b = new byte[1024];
while ((len = inputStream.read(b)) != -1) {
System.out.println(new String(b, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出客户端~~~~");
try {
if (outputStream != null) {
outputStream.close();
}
if (inputStream != null) {
inputStream.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果
1.服务端启动,进入阻塞状态,等待客户端的连接
2、客户端启动,连接服务端,给客户端发送消息,同时收到服务端回复的消息
3、服务端收到客户端的消息,然后给客户端发送消息
案例3
客户端用字符流的形式给服务端发送消息,服务端回复消息
服务端
package com.tk.socket.demo03;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author taoke
* @desc socket服务端,用字符流的形式给客户端发送消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
System.out.println("服务端已启动~~~~");
//开启端口9999的监听
serverSocket = new ServerSocket(9999);
//阻塞,等待客户端的连接
socket = serverSocket.accept();
System.out.println("客户端连接成功~~~~");
//通过字符流从通道读取服务端回复的消息
InputStream inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = bufferedReader.readLine();
System.out.println(line);
//通过字符流将消息写入到通道
OutputStream outputStream = socket.getOutputStream();
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello client,i am server");
bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,另一方必须使用readLine读取
bufferedWriter.flush();//字符流需要手动把数据刷新到通道
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出服务端~~~~");
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (socket != null) {
socket.close();
}
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
package com.tk.socket.demo03;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author taoke
* @desc socket客户端,用字符流的形式给服务端发送消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpClient {
public static void main(String[] args) {
Socket socket = null;
BufferedWriter bufferedWriter = null;
BufferedReader bufferedReader = null;
try {
socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("连接服务器成功~~~~~~");
OutputStream outputStream = socket.getOutputStream();
//通过字符流将消息写入到通道
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello server,i am client");
bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,另一方必须使用readLine读取
bufferedWriter.flush();//字符流需要手动把数据刷新到通道
//通过字符流从通道读取客户端回复的消息
InputStream inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = bufferedReader.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
} finally {//释放资源
System.out.println("退出客户端~~~~");
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果
1.服务端启动,进入阻塞状态,等待客户端的连接
2、客户端以字符流的形式给服务端发送消息,服务端给客户端回复消息
3、服务端收到客户端的消息,给客户端回复消息
案例4
客户端发送文件,服务端接收文件,并且服务端回复消息
服务端
package com.tk.socket.demo04;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author taoke
* @desc socket服务端,用字符流的形式给客户端发送消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
ByteArrayOutputStream bas = null;
try {
System.out.println("服务端已启动~~~~");
//1、开启端口9999的监听
serverSocket = new ServerSocket(9999);
//阻塞,等待客户端的连接
socket = serverSocket.accept();
System.out.println("客户端连接成功~~~~");
//2、接收客户端发送的图片
bis = new BufferedInputStream(socket.getInputStream());
bas = new ByteArrayOutputStream();
int len;
byte[] b = new byte[1024];
while ((len = bis.read(b)) != -1) {
bas.write(b, 0, len);
}
//图片存放路径
String destFilePath = "src\\temp.png";
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
bos.write(bas.toByteArray());
bos.flush();
//3、向客户端发送消息,已收到图片
bos = new BufferedOutputStream(socket.getOutputStream());
bos.write("server: 收到图片".getBytes());
bos.flush();
socket.shutdownOutput();//设置结束写入标记 重要
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("退出服务端~~~~");
try {
//释放资源
if (bos != null) {
bos.close();
}
if (bis != null) {
bis.close();
}
if (bas != null) {
bas.close();
}
if (socket != null) {
socket.close();
}
if (serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
package com.tk.socket.demo04;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
/**
* @author taoke
* @desc socket客户端,用字符流的形式给服务端发送消息
* @email 1504806660@qq.com
* @date 2022/2/16
*/
public class SocketTcpClient {
public static void main(String[] args) {
Socket socket = null;
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
FileInputStream fis = null;
ByteArrayOutputStream bas = null;
try {
//1、连接服务器
socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("连接服务器成功~~~~~~");
//2、向服务器发送图片
//从通道获取输出流
bos = new BufferedOutputStream(socket.getOutputStream());
String filePath = "d:\\desk.png";//本地图片存放路径
fis = new FileInputStream(filePath);//获取文件输入流
bis = new BufferedInputStream(fis);//转换为缓存字节流
bas = new ByteArrayOutputStream();//定义一个字节缓冲区
//将读取到的文件写入缓冲区 bas
byte[] b = new byte[1024];
int i;
while ((i = fis.read(b)) != -1) {
bas.write(b, 0, i);
}
bos.write(bas.toByteArray());//字节缓冲区数据bas 写入通道
bos.flush();//刷新
System.out.println("图片发送成功");
socket.shutdownOutput();//设置结束写入标记 重要
//3、接收服务器回复的消息
bis = new BufferedInputStream(socket.getInputStream());
int len;
byte[] buff = new byte[1024];
while ((len = bis.read(buff)) != -1) {
System.out.println(new String(buff, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {//释放资源
System.out.println("退出客户端~~~~");
try {
//释放资源
if (bos != null) {
bos.close();
}
if (bas != null) {
bas.close();
}
if (bis != null) {
bis.close();
}
if (fis != null) {
fis.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
运行结果
1.服务端启动,进入阻塞状态,等待客户端的连接
2、客户端向服务端发送图片,收到服务端回复的消息
3、服务端收到客户端的图片,保存到 "src"下