ByteChange.java/** * * @author Administrator */ public class ByteChange { //将int存入byte数组,使用小端模式 public static void intToByte(byte b[],int start,int num){ for(int i=start;i<start+4;i++){ b[i]=(byte)num; num>>>=8; } } //从byte数组中提取int,使用小端模式 public static int byteToInt(byte b[],int start){ int num=0; for(int i=3+start;i>=start;i--){ num=num<<8; num+=(0xff&(int)b[i]); } return num; } }
SendImageimport java.awt.image.BufferedImage; import java.io.*; import java.net.*; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.event.*; import javax.imageio.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; public class SendImage { //网络参数 final String addr="192.168.1.4"; final int myPort=12000; final int yourPort=10000; //数据包长度,数据长度,标识符长度 final int bufSize=1024; final int dataSize=1000; final int identifier=12; //用于判断回送包 final int backNum=10; final String backMes="getMessage"; // DatagramPacket packet; DatagramSocket socket; //数据 BufferedImage image; public SendImage(){ try{ socket=new DatagramSocket(myPort); socket.setSoTimeout(1000); while(true){ image = (new Robot()).createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); sendImage(); try{ Thread.sleep(20); }catch(InterruptedException e){
2: 用 ServerSocket 写个服务端,用 Socket 类写个客户端
3: ServerSocket 把图像字节流发过去
4: 客户端收到后显示出来就可以了
现在我弄到了一张图片可以显示了。。但是我用while循环的时候 第二张图片字节就和第一张的在一起了(图片的大小一直在变大)。。(我是字节传输的)。。
很乱了。。哎
怎么分组啊。。
大哥我的服务器这端代码是
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server extends Frame {
boolean flag = true;
File file = null;
Image image = null;
Socket socket = null;
ServerSocket server = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
InputStream is = null;
static int i = 0;
public Server() {
try {
server = new ServerSocket(6666);
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
Server server = new Server();
server.screen();
server.new MyThread().start();
} public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
} public void screen() {
this.setSize(1024, 768);
this.setLocation(0, 0);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setVisible(true);
this.setResizable(true);
} class MyThread extends Thread { public void run() {
while (flag) {
try {
is = socket.getInputStream();
File file = new File("e:/test"+i+".jpg");
FileOutputStream fis = new FileOutputStream(file);
int j = 0;
while ((j = is.read()) != -1) {
fis.write(j);
}
fis.flush();
i++;
fis.close();
is.close();
image = Toolkit.getDefaultToolkit()
.getImage(file.getPath());
repaint();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
flag = false;
} }
}
}
}
怎么改才可以图片更新呢
怎么分组啊。。
大哥我的服务器这端代码是
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class Server extends Frame {
boolean flag = true;
File file = null;
Image image = null;
Socket socket = null;
ServerSocket server = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
InputStream is = null;
static int i = 0;
public Server() {
try {
server = new ServerSocket(6666);
socket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
Server server = new Server();
server.screen();
server.new MyThread().start();
} public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
} public void screen() {
this.setSize(1024, 768);
this.setLocation(0, 0);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
this.setVisible(true);
this.setResizable(true);
} class MyThread extends Thread { public void run() {
while (flag) {
try {
is = socket.getInputStream();
File file = new File("e:/test"+i+".jpg");
FileOutputStream fis = new FileOutputStream(file);
int j = 0;
while ((j = is.read()) != -1) {
fis.write(j);
}
fis.flush();
i++;
fis.close();
is.close();
image = Toolkit.getDefaultToolkit()
.getImage(file.getPath());
repaint();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
flag = false;
} }
}
}
}
怎么改才可以图片更新呢
注意,一共有三个类.其中ByteChange.java,另两个类都要用到的,功能是实现int和byte数组的相互转化.
另外两个类,一个SendImage.java,用于发送.一个ReceiveImage.java,用于接收并显示.有几点注意的:
1.SendImage发送时,每发送一个数据包,是要求接收确认包的(这也是传输慢的原因),而且设置了超时时间,如果超时,会输出异常信息,不过程序可以继续执行.所以不要惊讶
2.ReceiveImage接收时.如果你用的是同一台电脑,显示的时候会发生有趣的反馈现象.嘿嘿,到时候你就知道了.不多说了,下面是程序
*
* @author Administrator
*/
public class ByteChange {
//将int存入byte数组,使用小端模式
public static void intToByte(byte b[],int start,int num){
for(int i=start;i<start+4;i++){
b[i]=(byte)num;
num>>>=8;
}
}
//从byte数组中提取int,使用小端模式
public static int byteToInt(byte b[],int start){
int num=0;
for(int i=3+start;i>=start;i--){
num=num<<8;
num+=(0xff&(int)b[i]);
}
return num;
}
}
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class SendImage {
//网络参数
final String addr="192.168.1.4";
final int myPort=12000;
final int yourPort=10000;
//数据包长度,数据长度,标识符长度
final int bufSize=1024;
final int dataSize=1000;
final int identifier=12;
//用于判断回送包
final int backNum=10;
final String backMes="getMessage";
//
DatagramPacket packet;
DatagramSocket socket;
//数据
BufferedImage image;
public SendImage(){
try{
socket=new DatagramSocket(myPort);
socket.setSoTimeout(1000);
while(true){
image = (new Robot()).createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
sendImage();
try{
Thread.sleep(20);
}catch(InterruptedException e){
}
}
}catch(Exception e){
e.printStackTrace();
}
}
public void sendImage(){
try {
//image = ImageIO.read(new File("Screen.bmp"));
if(image==null){
return;
}
int rgbArray[]=new int[image.getWidth()*image.getHeight()];
image.getRGB(0, 0, image.getWidth(), image.getHeight(), rgbArray, 0, image.getWidth());
//下面先计算数据大小,分组情况
//每个数据包的前12个字节为序列号,最后4个字节为结尾标识,所以数据区只有1000个字节
int size=rgbArray.length*4;
int number=size/dataSize;
if(size%dataSize!=0){
number++;
}
//传送数组组头
byte b[]=new byte[bufSize];
fillMessage(0,b);
//填入number
ByteChange.intToByte(b, identifier, number);
//填入总数据大小
ByteChange.intToByte(b, identifier+4, size);
//填入image的长度和宽度
ByteChange.intToByte(b, identifier+8, image.getWidth());
ByteChange.intToByte(b, identifier+12, image.getHeight());
packet=new DatagramPacket(b,b.length,InetAddress.getByName(addr),yourPort);
sendMessage(packet);
//下面分组发送数据包体
for(int i=0;i<number;i++){
//这里还是用数组b
//先清空数组
for(int j=0;j<bufSize;j++){
b[j]=0;
}
//填充标识
fillMessage(1,b);
//填充序列号
ByteChange.intToByte(b, identifier, i);
//填充数据长度
int length=size-dataSize*(i);
if(length>dataSize){
length=dataSize;
}
ByteChange.intToByte(b, identifier+4, length);
//填充数据 说明一下,length一定是4的倍数
int start=dataSize*(i)/4;
for(int j=0;j<length;j+=4){
ByteChange.intToByte(b, identifier+8+j, rgbArray[start+j/4]);
}
//发送
packet=new DatagramPacket(b,b.length,InetAddress.getByName(addr),yourPort);
sendMessage(packet);
}
} catch (IOException ex) {
Logger.getLogger(SendImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void fillMessage(int category,byte buffer[]){
if(buffer.length!=bufSize){
System.out.println("数据包大小错误");
return;
}
switch(category){
case 0: //数据头组,包含数据大小,分组多少等信息
{
byte b[]=(new String("[][][][][]01")).getBytes();
for(int i=0;i<identifier;i++){
buffer[i]=b[i];
}
break;
}
case 1: //数据组体
{
byte b[]=(new String("[][][][][]02")).getBytes();
for(int i=0;i<identifier;i++){
buffer[i]=b[i];
}
break;
}
}
byte b[]=(new String("endl")).getBytes();
for(int i=bufSize-4;i<bufSize;i++){
buffer[i]=b[i-bufSize+4];
}
}
public void sendMessage(DatagramPacket dp){
while(true){
try {
socket.send(dp);
//发送后要求返回一个标识,否则重发
byte b[]=new byte[backNum];
DatagramPacket temp=new DatagramPacket(b,b.length);
socket.receive(temp);
String s=new String(b);
if(s.equals(backMes)){
//System.out.println("收到回送");
break;
}
} catch (IOException ex) {
Logger.getLogger(SendImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]){
new SendImage();
}
}
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class ReceiveImage {
//网络参数
final String addr="localhost";
final int myPort=10000;
//final int yourPort=12000;
//数据包长度,数据长度,标识符长度
final int bufSize=1024;
final int dataSize=1000;
final int identifier=12;
//用于判断回送包
final int backNum=10;
final String backMes="getMessage";
//
DatagramPacket packet;
DatagramSocket socket;
//数据
BufferedImage image;
//显示
JFrame frame;
JPanel imagePane;
JScrollPane contentPane;
public ReceiveImage(){
try {
socket = new DatagramSocket(myPort);
//socket.setSoTimeout(1000);
frame=new JFrame();
imagePane=new JPanel(){
public void paint(Graphics g){
g.setColor(Color.white);
g.fillRect(0, 0, this.WIDTH, this.HEIGHT);
if(image!=null){
g.drawImage(image, -5, -31, null);
}
}
};
imagePane.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
contentPane=new JScrollPane(imagePane);
frame.setContentPane(contentPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(0,0,400,400);
frame.setVisible(true);
while(true){
getImage();
imagePane.repaint();
}
} catch (SocketException ex) {
Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void getImage(){
byte b[];
int width,height;
while(true){
//先获取数据包头
b=getMessage();
//先判断一下数组是不是null
if(b==null)
continue;
//判断一下,是不是报头
String head=new String(b,0,identifier);
if(head.equals("[][][][][]01")){
//是报头,跳出循环
callBack();
break;
}
}
//从报头提取数据包个数信息
int number=ByteChange.byteToInt(b, identifier);
int size=ByteChange.byteToInt(b, identifier+4);
width=ByteChange.byteToInt(b, identifier+8);
height=ByteChange.byteToInt(b, identifier+12);
System.out.println("收到数据包头,下面将接收"+number+"个数据包"+",总大小为:"+size+"字节");
System.out.println("图像长度:"+width+",宽度:"+height);
//下面分组接收数据
int rgbArray[]=new int[size/4];
for(int i=0;i<number;i++){
//这里还是用数组b
while(true){
b=getMessage();
//判断标识
String head=new String(b,0,identifier);
if(!head.equals("[][][][][]02")){
//不是报体,继续循环
//不过呢,先判断一下,如果是报头,说明上次的回送不成功,重新回送
callBack();
continue;
}
//判断序列号
int serial=ByteChange.byteToInt(b, identifier);
if(serial==i){
//序列号匹配,跳出循环
callBack();
break;
}
//如果序列号不匹配,说明以前的回送不成功,重新回送
callBack();
}
//获取数据长度
int length=ByteChange.byteToInt(b, identifier+4);
//攻取数据 说明一下,length一定是4的倍数
int start=dataSize*(i)/4;
for(int j=0;j<length;j+=4){
//ByteChange.intToByte(b, identifier+8+j, rgbArray[start+j/4]);
rgbArray[start+j/4]=ByteChange.byteToInt(b, identifier+8+j);
}
}
image=new BufferedImage(width,height,5);
image.setRGB(0, 0, width, height, rgbArray, 0, width);
try {
ImageIO.write(image, "bmp", new FileOutputStream("1.bmp"));
} catch (IOException ex) {
Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public byte[] getMessage(){
try {
byte[] b = new byte[bufSize];
packet = new DatagramPacket(b, b.length);
socket.receive(packet);
//先判断一下b的最后四个字节是否是文件尾的标志,如果不是,返回null
String end=new String(b,b.length-4,4);
if(!end.equals("endl")){
return null;
}
return b;
} catch (IOException ex) {
Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
public void callBack(){
//收到后回送
byte back[]=(new String("getMessage")).getBytes();
DatagramPacket dp=new DatagramPacket(back,back.length,packet.getAddress(),packet.getPort());
try {
socket.send(dp);
} catch (IOException ex) {
Logger.getLogger(ReceiveImage.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String args[]){
new ReceiveImage();
}
}