使用Socket 实现最简单的通讯
客户端
package SocketDemo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Created by kumamon on 2021/5/28.
*
* TCP 通信demo
*/
public class Socket_Clicent {
public static void main(String[] args) throws IOException {
Socket socket =new Socket("127.0.0.1",8888);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好服务器".getBytes());
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len=0;
while ((len=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes));
}
socket.close();
}
}
服务端
package SocketDemo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by kumamon on 2021/5/28.
*
* 服务器的流也是 使用 client 传递过来的socket获取的
* 说白了 socket就是一个管道
*/
public class Socket_Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(8888);
Socket accept = serverSocket.accept(); //获取和clicent 交互的 socket
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream();
byte[] bytes = new byte[1024];
StringBuilder sb=new StringBuilder();
int len=0;
while ((len=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes));
outputStream.write("服务器收到了,谢谢".getBytes());
}
}
}
简单的通讯 心跳 重连
客户端
package Socket_QQ;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
/**
* Created by kumamon on 2021/5/28.
*/
public class TCP_Client {
private static Socket socket;
public static boolean connection_state = false;
public static void main(String[] args){
while (!connection_state) {
connect();
try {
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
}
}
private static void connect(){
try {
socket = new Socket("127.0.0.1", 10086);
connection_state = true;
new Thread(new Client_listen(socket)).start();
new Thread(new Client_send(socket)).start();
new Thread(new Client_heart(socket)).start();
}catch (Exception e){
e.printStackTrace();
connection_state = false;
}
}
public static void reconnect(){
while (!connection_state){
System.out.println("正在尝试重新链接.....");
connect();
try {
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
class Client_listen implements Runnable{
private Socket socket;
Client_listen(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
InputStream ois = socket.getInputStream();
int len=0;
byte[] bytes = new byte[1024];
while ((len=ois.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
}catch (Exception e){
e.printStackTrace();
}
}
}
class Client_send implements Runnable{
private Socket socket;
Client_send(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream oos = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
while (true){
System.out.print("请输入你要发送的信息:");
String string = scanner.nextLine();
oos.write(string.getBytes());
oos.flush();
}
}catch (Exception e){
e.printStackTrace();
try {
socket.close();
TCP_Client.connection_state = false;
TCP_Client.reconnect();
}catch (Exception ee){
ee.printStackTrace();
}
}
}
}
class Client_heart implements Runnable{
private Socket socket;
Client_heart(Socket socket){
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream oos = socket.getOutputStream();
System.out.println("心跳包线程已启动...");
while (true){
Thread.sleep(5000);
oos.write("心跳包..".getBytes());
oos.flush();
}
}catch (Exception e){
e.printStackTrace();
try {
socket.close();
TCP_Client.connection_state = false;
TCP_Client.reconnect();
}catch (Exception ee){
ee.printStackTrace();
}
}
}
}
服务端
package Socket_QQ;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* Created by kumamon on 2021/5/28.
*/
public class TCP_Server {
public static ServerSocket serverSocket;
private static Socket socket;
public static void main(String[] args) {
try {
System.out.println("服务器已经启动....");
serverSocket = new ServerSocket(10086);
while (true) {
//阻塞的。只有当socket 有连接后才会执行后面的程序
//有可能断开。也有可能多个客户端连接,所以这里使用 死循环,一直接收
socket = serverSocket.accept();
new Thread(new Server_getMessage(socket)).start();
new Thread(new Server_sendMessage(socket)).start();
}
} catch (IOException e) {
try {
socket.close();
serverSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
class Server_getMessage implements Runnable {
private Socket socket;
public Server_getMessage(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len=0;
while ((len=is.read(bytes))!=-1) { //死循环一直读取消息
String message = new String(bytes,0,len);
System.out.println();
System.out.println("收到消息:" + message);
}
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
class Server_sendMessage implements Runnable {
private Socket socket;
public Server_sendMessage(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println("已经有客户端连接------");
OutputStream os = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
while (true) { //scanner 默认是阻塞的,所以这个死循环必须得通畅以后才可以继续执行,所以必须输入一次后才可以继续执行
System.out.print("发送:");
String message = scanner.next();
os.write(message.getBytes());
os.flush();
}
} catch (IOException e) {
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
}
模拟文件上传
客户端
package Socket_File_UpLoad;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Created by kumamon on 2021/5/31.
*/
public class Socket_Filte_UpLoad_client {
public static void main(String[] args) throws IOException {
//创建本地输入流对象 准备读取需要上传的数据
FileInputStream fis = new FileInputStream("d:\\1.jpg");
Socket socket = new Socket("127.0.0.1", 10087); // 创建和服务器交互的socket对象,
OutputStream outputStream = socket.getOutputStream(); //创建和服务器交互的输出流对象。准备向服务器发送数据
/**
* 注意:
* 因为 我们读文件是以-1结束的
* 所以当文件结束后,不会进入循环
* 那么-1这个结束标记不会上传到服务器
* 所以服务器没有结束标记会一直阻塞(read 的方法,如果没有消息,会一直阻塞的)
*
* 客户端会等待服务器回传的“上传成功”
* 所以也会阻塞
* 这个时候我们需要结束客户端发送的输出流(模拟结束标记)
* */
int len;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
socket.shutdownOutput(); //关闭输出流,那么客户端的输入流结束
InputStream inputStream = socket.getInputStream(); //获取服务器回传的数据
if(socket.isConnected()){
while ((len = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0, len));
}
}
fis.close(); //关闭流
socket.close();
}
}
服务端
package Socket_File_UpLoad;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/**
* Created by kumamon on 2021/5/31.
*/
public class Socket_File_UpLoad_Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(10087);
while (true){
Socket socket = serverSocket.accept(); //通过服务器的对象 获取客户端的socket
InputStream is = socket.getInputStream(); //获取客户端的输入流 ,准备接受数据
String filename=System.currentTimeMillis()+ new Random().nextInt(99999)+".jpg";
File file = new File("E:\\upload");//创建需要上传文件的文件夹
if (!file.exists()) { //如果文件夹不存在
file.mkdirs(); //创建文件夹
}
//创建需要保存文件的输出流,
FileOutputStream fos = new FileOutputStream(file + "\\"+filename);
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) { //死循环一直读取消息
fos.write(bytes, 0, len);
}
OutputStream outputStream = socket.getOutputStream(); //获取socket的输入流
outputStream.write("上传成功".getBytes()); //向客户端发送 上传成功
/**
* 三个流都需要关闭,
* */
fos.close();
socket.close();
}
// serverSocket.close(); 如果需要服务器一直启动,就不需要关闭serverSocket
}
}