Socket
单向通信
简介
单向通信就是一方发,一方收
例如下面的代码就是客户端发,服务端收
服务端
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/***
* 单向传输,接收来自客户端传输过来的文件流
*/
public class ServerFileSocket {
public static void main(String[] args) {
try(
ServerSocket serverSocket = new ServerSocket(8080);
) {
Socket socket = serverSocket.accept();
while(true) {
new Thread(new ServerFileSocketHand(socket)).start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务端处理类
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
public class ServerFileSocketHand implements Runnable{
private Socket socker;
public ServerFileSocketHand(Socket socker) {
this.socker = socker;
}
@Override
public void run() {
StringBuilder sBuilder = new StringBuilder();
sBuilder.append("path");//路径写自己对应的
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = sBuilder.append(dateFormat.format(new Date())).append(UUID.randomUUID().toString().replaceAll("-", "")).append(".jpg").toString();
System.out.println("fileName:"+fileName);
try(
InputStream in = socker.getInputStream();
FileOutputStream fStream = new FileOutputStream(fileName);
) {
byte[] bs = new byte[10240];
int len = 0;
while( ( len = in.read(bs) ) != -1 ) {
fStream.write(bs, 0, len);
}
fStream.flush();
} catch (Exception e) {
// TODO: handle exception
}finally {
try {
socker.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class ClientFileSocket {
public static void main(String[] args) {
try(
Socket socket = new Socket("127.0.0.1", 8080);
OutputStream out = socket.getOutputStream();
FileInputStream fileInStream = new FileInputStream("path.jpg");//写自己对应的路径
) {
byte[] bs = new byte[10240];
int len = 0;
while( ( len = fileInStream.read(bs ) ) != -1) {
out.write(bs,0,len);
}
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
半双工
简介
可双向通信就是,但是一次只能有一方发送
服务端
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8080);
while(true) {
Socket socket = serverSocket.accept();
new Thread(new ServerHandle(socket)).start();
}
}
}
服务端处理
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class ServerHandle implements Runnable{
private Socket socket;
public ServerHandle(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
OutputStream outputStream = socket.getOutputStream();
){
String message = reader.readLine();
while( !"end".equals(message)) {
//获取客户端消息
System.out.println("客户端发送消息:\t"+message);
//发送客户端信息
outputStream.write("ok\n".getBytes());
message = reader.readLine();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户端
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class SocketClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8080);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
OutputStream outputStream = socket.getOutputStream();
Scanner in = new Scanner(System.in);
String message = in.next();
while( !"end".equals(message) ) {
/***
* 如果客户端想要发送多行的话或者间隔两次才服务端才回复的话,
* 那么需要特殊的标记 比如说设定头部一位 0|1 表示是否有后续 或者使用$$等自定义符号来判断
*/
//向服务端发送消息
outputStream.write( (message+"\n").getBytes() );
outputStream.flush();
//获取服务端的回复
String res = reader.readLine();
System.out.println("服务端恢复:\t"+res);
message = in.next();
}
outputStream.write( (message+"\n").getBytes() );
outputStream.flush();
//关闭流
outputStream.close();
reader.close();
//关闭连接
socket.close();
}
}
全双工
简介
服务端和客户端可以同时发送数据
服务端
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8080);
while(true) {
Socket socket = serverSocket.accept();
new Thread(new WriteHandle(socket)).start();
new Thread(new ReadHandle(socket,"服务端")).start();
}
}
}
客户端
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 8080);
new Thread(new WriteHandle(socket)).start();
new Thread(new ReadHandle(socket,"客户端")).start();
}
}
读处理
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReadHandle implements Runnable{
private Socket socket;
private String serverName;
public ReadHandle(Socket socket,String serverName) {
this.socket = socket;
this.serverName = serverName;
}
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = reader.readLine();
while( !"end".equals(message) ) {
//获取客户端消息
System.out.println(serverName+"收到:\t"+message);
//发送客户端信息
message = reader.readLine();
}
System.out.println(serverName+"发来:\t"+message);
socket.shutdownInput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//检测是否需要关闭socket
SocketUtil.closeSocket(socket);
}
}
}
写处理
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class WriteHandle implements Runnable{
private Socket socket;
public WriteHandle(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream outputStream = socket.getOutputStream();
Scanner in = new Scanner(System.in);
String message = in.next();
while( !"end".equals(message)) {
//发送客户端信息
outputStream.write((message+"\n").getBytes());
message = in.next();
}
outputStream.write((message+"\n").getBytes());
outputStream.flush();
socket.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
//检查是否需要关闭socket
SocketUtil.closeSocket(socket);
}
}
}
socket工具类
import java.io.IOException;
import java.net.Socket;
public class SocketUtil {
public static void closeSocket(Socket socket) {
if( socket!= null && !socket.isClosed() && socket.isInputShutdown() && socket.isOutputShutdown()) {
synchronized (socket) {
if( socket!= null && !socket.isClosed() && socket.isInputShutdown() && socket.isOutputShutdown() ) {
try {
System.out.println("关闭了");
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}