服务器:利用piped管道在线程中传递数据。此简易服务器有点srs 服务器的味道。但实际使用验证,延时基本为零,真正做到实时监控。实际使用带宽在2-3M左右,比stmp协议传输大一倍左右。
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Khd3 {
static int zise;
public static void main(String[] args) {
try {
PipedOutputStream pipedOutputStream = new PipedOutputStream();
PipedInputStream pipedInputStream = new PipedInputStream(pipedOutputStream,90000000);
Thread thread1 = new Thread(new Runnable() {
public void run() {
try {
//---------------------------------------------------------------------------------------
ServerSocket serverSocket=new ServerSocket(3000);
while(true) {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
while(true) {
byte[] b = (byte[]) objectInputStream.readObject();
Khd3.zise=b.length;
pipedOutputStream.write(b);
pipedOutputStream.flush();
b=null;
}
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
public void run() {
try {
//-----------------------------------------------------------------------------------------
ServerSocket serverSocket=new ServerSocket(3001);
while(true) {
Socket socket = serverSocket.accept();
OutputStream outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
while(true) {
byte[] b1 = new byte[Khd3.zise];
pipedInputStream.read(b1);
objectOutputStream.writeObject(b1);
objectOutputStream.flush();
b1=null;
}
}
//-----------------------------------------------------------------------------------------
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
thread2.start();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
采集客户端:
import org.bytedeco.javacv.*;
import org.bytedeco.javacv.Frame;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.Socket;
public class Khd1 {
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket=new Socket("114.132.48.×",3000);
OutputStream outputStream=socket.getOutputStream();
ObjectOutputStream outputStream2=new ObjectOutputStream(outputStream);
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("/dev/video0"); //读摄像头
grabber.setImageWidth(360);
grabber.setImageHeight(270); //这两句严重影响带宽。
grabber.start();
Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
while(true) {
Frame frame = grabber.grabFrame();
BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);
ByteArrayOutputStream outputStream1=new ByteArrayOutputStream();
ImageIO.write(bufferedImage, "jpg", outputStream1); //支持bmp,png,jpg,前两种没压缩
byte[] b=outputStream1.toByteArray();
outputStream2.writeObject(b);
outputStream2.flush();
outputStream1=null;
Thread.sleep(1000/10); //图片帧率,这是大概数字,因为压缩还要占用时间
}
}
}
显示客户端:
import org.bytedeco.javacv.CanvasFrame;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Socket socket=new Socket("114.132.48.×",3001);
InputStream inputStream = socket.getInputStream();
ObjectInputStream inputStream1=new ObjectInputStream(inputStream);
CanvasFrame canvas = new CanvasFrame("播放");//新建一个预览窗口
while(true) {
byte[] b= (byte[]) inputStream1.readObject();
ByteArrayInputStream inputStream2=new ByteArrayInputStream(b);
Image image = ImageIO.read(inputStream2);
canvas.showImage(image);
}
}
}
=====================================================================
改进后的服务器,已加入异常处理。如果客户端异常退出,服务器也正常运行,两客户端再次登录就正常工作。还有一问题,客户端启动是有顺序的,先启动采集客户端,再启动显示客户端。如果先启动显示客户端,等待时间要长些,也可正常工作。3000端口用于采集,3001端口用于显示。
如果打不开,可能是服务器的网站限速了,.我的腾讯公网刚开始好好的,最近上传就只有几十K的带宽打不开了。如想体验就在自己的局域网内看看。
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Khd3 {
static int zise;
static PipedOutputStream pipedOutputStream;
static PipedInputStream pipedInputStream;
public static void main(String[] args) throws IOException {
ServerSocket serverSocket1 = new ServerSocket(3000);
ServerSocket serverSocket2 = new ServerSocket(3001);
while(true) {
zise=0;
pipedOutputStream=new PipedOutputStream();
pipedInputStream=new PipedInputStream(pipedOutputStream,9000000);
Socket socket1 = serverSocket1.accept();
Socket socket2=serverSocket2.accept();
Cj t1=new Cj(socket1);
t1.start();
Bf t2=new Bf(socket2);
t2.start();
}
}
}
class Cj extends Thread {
Socket socket;
Cj(Socket socket) {
this.socket=socket;
}
public void run() {
InputStream inputStream = null;
try {
inputStream = socket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
while (true) {
byte[] b = (byte[]) objectInputStream.readObject();
Khd3.zise = b.length;
Khd3.pipedOutputStream.write(b);
Khd3.pipedOutputStream.flush();
b = null;
}
} catch (IOException e) {
try {
Khd3.pipedOutputStream.close();
inputStream.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
class Bf extends Thread {
Socket socket;
Bf(Socket socket) {
this.socket = socket;
}
public void run() {
OutputStream outputStream=null;
try {
outputStream = socket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
while (true) {
byte[] b1 = new byte[Khd3.zise];
Khd3.pipedInputStream.read(b1);
objectOutputStream.writeObject(b1);
objectOutputStream.flush();
b1 = null;
}
} catch (IOException e) {
try {
Khd3.pipedInputStream.close();
outputStream.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
throw new RuntimeException(e);
}
}
}