【中文名】无线牵
【英文名】Wireless Linker
【组成】PC端(PC版)WirelessLinker-PC.jar、Mobile端(手机版)WirelessLinker.jar
【作者】火种工作室(Tinder Studio)
【邮箱】tinderstudio@163.com
【使用注意】
1、本软件使用J2ME开发,使用前请确认你的手机支持JSR75;
2、在传输文件给Mobile端时,请注意文件后缀,经本人在Nokia 5800上测试发现一些后缀是禁止传输的,
所以传输前请先将后缀改为可用的后缀,如jpg,mp3等,然后再进行传输;
3、本软件在基于进行使用的,即手机版的使用是基于WLAN,所以请在使用前确认你的旁边局域网通讯的条件。
4、本软件不具备Nokia对一些特殊功能使用时应有的签名和证书,所以在使用过程会出现一些提示询问
用户确认,均是Nokia的认证机制所致,不便之处,敬请谅解;
5、因为条件限制,本软件只在Nokia 5800真机上测试过,对于其他手机用户可自行尝试,如果不能使用只要
卸载即可,不会残留信息。
6、因为本人能力有限,如果在使用过程中遇到异常的情况,希望您能多多提供意见和建议(联系方式请见
上文),本人在此谢过。
7、有网友反应安装了JDK后运行PC端会出现can not find main class ,program will exit异常,这是因为本
软件使用JDK1.6版本编译,所以请使用前确认你的JDK版本。
【版本】1.0
【功能说明】
1、显示局域网用户IP列表
2、局域网发送接收文件传输并支持文件覆盖
3、文件传输带进度条显示
4、支持PC-PC、PC-Mobile、Moblie-Mobile的文件传输
【使用步骤】
1、在电脑上打开PC端,并在手机上打开Mobile端,这时PC端的IP列表如图:
其中192.168.0.100是本机IP,192.168.0.101是Mobile端的IP;
2、点击Mobile端的IP,然后点击发送,会弹出文件选择框,选择你要传送的文件(注意一些后缀可能受限制,建议先改为jpg等图片后缀)
3、这时Mobile端会提示收到PC端的发送文件请求,选择“接收”,这时会弹出目录选择框(会提示是否允许文件访问,一路按是)点击“选择”确认保存文件的路径,程序就开始将文件从PC端传送给Mobile端,传输过程如下:
4、传输完毕后,程序提示如下:
5、从Mobile端传给PC端也类似,先选择相应的IP再点击“发送”按钮选择文件.....。
很抱歉,本来应该连同Mobile端的图片一起上传,但可惜我手头刚好没有照相机,手机又无法截图,所以请各位将就着看,希望这个软件能给大家提供一些方便(拿着一条数据线在USB跟手机上拔插真的很不爽,:))
部分源码:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.Datagram;
import javax.microedition.io.ServerSocketConnection;
import javax.microedition.io.SocketConnection;
import javax.microedition.io.UDPDatagramConnection;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
/**
* 无线牵
* @version 1.0
* 功能:
* 1、显示局域网用户IP列表
* 2、支持局域网发送接收文件传输
* 3、文件传输带进度条显示
*
*/
public class WirelessLinker extends MIDlet implements CommandListener {
public static final char COMMAND_HI='H';
public static final char COMMAND_REPLY='R';
public static final char COMMAND_QUIT='Q';
public static final char COMMAND_SEND='S';
public static final char COMMAND_ACCEPT='A';
public static final char COMMAND_FINISH='F';
public static final char COMMAND_ERROR='E';
public static final int STATE_NORMAL=0x01;
public static final int STATE_READY=0x02;
public static final int STATE_BUSY=0x04;
public static final int PORT=6548;
private Command exitCommand = new Command("退出", Command.EXIT, 2);
private Command sendCommand = new Command("发送", Command.ITEM, 2);
private Command aboutCommand=new Command("关于",Command.ITEM,2);
private Command acceptCommand = new Command("接受", Command.OK, 2);
private Command rejectCommand = new Command("拒绝", Command.CANCEL, 2);
private Command okCommand=new Command("确定",Command.OK,1);
private UDPServer udpServer;
private UDPClient udpClient;
private TCPServer tcpServer;
private Form form;
private ChoiceGroup choiceGroup;
private FileInfo receivingFileInfo;
private FileInfo sendingFileInfo;
private DirectoryChooser directoryChooser;
private Form aboutForm;
public WirelessLinker() {
try {
udpServer=new UDPServer(){
public void receive(final Datagram dg) {
if(form!=null)
{
String data=new String(dg.getData()).trim();
final String ip=getIP(dg.getAddress());
int index=-1;
switch(data.charAt(0))
{
case COMMAND_HI:
udpClient.sendReply(ip);
case COMMAND_REPLY:
if(data.length()==1)
{
index=-1;
for(int i=0;i<choiceGroup.size();i++)
{
if(choiceGroup.getString(i).equals(ip))
{
index=i;
break;
}
}
if(index==-1)
{
choiceGroup.append(ip,null);
System.out.println("reply");
}
}
break;
case COMMAND_QUIT:
if(data.length()==1)
{
index=-1;
for(int i=0;i<choiceGroup.size();i++)
{
if(choiceGroup.getString(i).equals(ip))
{
index=i;
break;
}
}
if(index!=-1)
{
choiceGroup.delete(index);
}
}
break;
case COMMAND_SEND:
try {
String info=new String(dg.getData(),"UTF-8");
index=-1;
index=info.indexOf('@',2);
if(index!=-1)
{
final String fileName=info.substring(2,index);
String fileSize=info.substring(index+1,info.length()).trim();
receivingFileInfo=new FileInfo(fileName,Long.parseLong(fileSize));
System.out.println(info+","+fileName+","+fileSize);
final Alert alert = new Alert("传输请求", ip+"请求传输文件:"+receivingFileInfo.getFileName()+"("+receivingFileInfo.getStringFileSize()+"),是否接受?",null,AlertType.CONFIRMATION);
alert.addCommand(acceptCommand);
alert.addCommand(rejectCommand);
alert.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable d) {
if (c==acceptCommand) {
directoryChooser=new DirectoryChooser(Display.getDisplay(WirelessLinker.this)){
public void doCancel() {
alert.setTimeout(1);
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
public void doSelect(String currentPath) {
try {
final FileConnection fc=(FileConnection)Connector.open("file:///"+currentPath+fileName);
if(fc.exists())
{
final Alert alert=new Alert("是否替换","E盘存在同名文件:"+receivingFileInfo.getFileName()+",确定替换文件?",null,AlertType.CONFIRMATION);
alert.addCommand(acceptCommand);
alert.addCommand(rejectCommand);
alert.setCommandListener(new CommandListener() {
public void commandAction(Command c, Displayable arg1) {
if (c==acceptCommand) {
try {
fc.delete();
fc.create();
receivingFileInfo.setFileConnection(fc);
System.out.println("accept"+"@"+receivingFileInfo.getFileName()+"@"+receivingFileInfo.getFileSize()+","+ip);
udpClient.send((COMMAND_ACCEPT+"@"+receivingFileInfo.getFileName()+"@"+receivingFileInfo.getFileSize()).getBytes("UTF-8"),ip);
} catch (IOException e1) {
e1.printStackTrace();
}finally{
alert.setTimeout(1);
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
}
else if (c==rejectCommand) {
alert.setTimeout(1);
Display.getDisplay(WirelessLinker.this).setCurrent(directoryChooser);
}
}
});
Display.getDisplay(WirelessLinker.this).setCurrent(alert);
}
else
{
fc.create();
receivingFileInfo.setFileConnection(fc);
System.out.println("accept"+"@"+receivingFileInfo.getFileName()+"@"+receivingFileInfo.getFileSize()+","+ip);
try {
udpClient.send((COMMAND_ACCEPT+"@"+receivingFileInfo.getFileName()+"@"+receivingFileInfo.getFileSize()).getBytes("UTF-8"),ip);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
} catch (IOException e) {
e.printStackTrace();
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
}
};
alert.setTimeout(1);
Display.getDisplay(WirelessLinker.this).setCurrent(directoryChooser);
}
if (c==rejectCommand) {
alert.setTimeout(1);
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
}
});
Display.getDisplay(WirelessLinker.this).setCurrent(alert,form);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
break;
case COMMAND_ACCEPT:
try {
String info=new String(dg.getData(),"UTF-8");
index=-1;
index=info.indexOf('@',2);
if(index!=-1)
{
System.out.println(info.trim());
String fileName=info.substring(2,index);
String fileSize=info.substring(index+1,info.length()).trim();
FileInfo fileInfo=new FileInfo(fileName,Long.parseLong(fileSize));
if(fileInfo.equals(sendingFileInfo))
{
Alert alert=new Alert("发送文件","文件"+sendingFileInfo.getFileName()+"发送中...",null,AlertType.INFO);
alert.setIndicator(new Gauge(null,false,100,0));
alert.setTimeout(Alert.FOREVER);
Display.getDisplay(WirelessLinker.this).setCurrent(alert);
SocketConnection sc=TCPClient.connect(ip);
OutputStream os=sc.openOutputStream();
InputStream is=sendingFileInfo.getFileConnection().openInputStream();
byte[] buffer = new byte[4096];
long byteSum=0;
int byteRead = 0;
while((byteRead=is.read(buffer))!=-1)
{
byteSum+=byteRead;
if(sendingFileInfo.getFileSize()>0)
alert.getIndicator().setValue((int)(byteSum*100/sendingFileInfo.getFileSize()));
else
alert.getIndicator().setValue(0);
os.write(buffer,0,byteRead);
}
is.close();
os.close();
sc.close();
sendingFileInfo.getFileConnection().close();
System.out.println("File send finish");
alert.setIndicator(null);
alert.setString("文件"+sendingFileInfo.getFileName()+"("+sendingFileInfo.getStringFileSize()+")"+"发送完毕!");
alert.setTitle("发送完毕");
alert.setTimeout(1500);
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
};
udpClient=new UDPClient();
udpClient.start();
tcpServer=new TCPServer(){
public void doSocket(final SocketConnection sc) {
new Thread(){
public void run() {
//接收文件
FileConnection fc=receivingFileInfo.getFileConnection();
try {
OutputStream os=fc.openOutputStream();
InputStream is=sc.openInputStream();
byte[] buffer=new byte[4096];
long byteSum=0;
int byteRead = 0;
Alert alert=new Alert("接收文件","文件"+receivingFileInfo.getFileName()+"接收中...",null,AlertType.INFO);
alert.setIndicator(new Gauge(null,false,100,0));
Display.getDisplay(WirelessLinker.this).setCurrent(alert);
alert.setTimeout(Alert.FOREVER);
while((byteRead=is.read(buffer))!=-1)
{
byteSum+=byteRead;
System.out.println("receive:"+byteSum);
if(receivingFileInfo.getFileSize()>0)
alert.getIndicator().setValue((int)(byteSum*100/receivingFileInfo.getFileSize()));
else
alert.getIndicator().setValue(0);
os.write(buffer,0,byteRead);
}
is.close();
os.close();
fc.close();
sc.close();
alert.setIndicator(null);
alert.setString("文件"+receivingFileInfo.getFileName()+"("+receivingFileInfo.getStringFileSize()+")"+"接收完毕!");
alert.setTitle("接收完毕");
alert.setTimeout(1500);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
};
} catch (IOException e1) {
e1.printStackTrace();
}
choiceGroup=new ChoiceGroup("本机IP:"+udpServer.getLocalAddress(),ChoiceGroup.EXCLUSIVE);
form = new Form("无线牵1.0");
form.append(choiceGroup);
form.addCommand(exitCommand);
form.addCommand(sendCommand);
form.addCommand(aboutCommand);
form.setCommandListener(this);
Display.getDisplay(this).setCurrent(form);
}
protected void destroyApp(boolean arg0){}
protected void pauseApp() {}
protected void startApp() throws MIDletStateChangeException {
udpServer.start();
tcpServer.start();
System.out.println("server has start");
udpClient.sendHi(udpServer.getLocalBroadcastAddress());
udpClient.sendHi(udpServer.getLocalBroadcastAddress());
}
public void commandAction(Command c, Displayable d) {
if (c == exitCommand) {
udpClient.sendExit(udpServer.getLocalBroadcastAddress());
udpClient.sendExit(udpServer.getLocalBroadcastAddress());
try {
/*注意此处要sleep否则主线程会占用udpClient的CPU使其无法执行任务*/
Thread.sleep(500);
udpClient.close();
udpClient.join();
udpServer.close();
udpServer.join();
tcpServer.close();
tcpServer.join();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
destroyApp(true);
notifyDestroyed();
} else if (c == sendCommand&&choiceGroup.getSelectedIndex()!=-1) {
final String ip=choiceGroup.getString(choiceGroup.getSelectedIndex());
FileChooser fileChooser=new FileChooser(Display.getDisplay(this)){
public void doCancel() {
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
public void doSelect(final String currentPath,final String fileName) {
Display.getDisplay(WirelessLinker.this).setCurrent(form);
try {
FileConnection fc=(FileConnection)Connector.open("file:///"+currentPath+fileName);
long size=fc.fileSize();
udpClient.send((COMMAND_SEND+"@"+fileName+"@"+size).getBytes("UTF-8"), ip);
WirelessLinker.this.sendingFileInfo=new FileInfo(fileName,size);
WirelessLinker.this.sendingFileInfo.setFileConnection(fc);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}};
Display.getDisplay(this).setCurrent(fileChooser);
} else if(c==aboutCommand)
{
if(aboutForm==null)
{
aboutForm=new Form("关于");
aboutForm.append("无线牵 v1.0\r\n\r\n");
try {
aboutForm.append(Image.createImage(this.getClass().getResourceAsStream("/logo.png")));
} catch (IOException e) {
e.printStackTrace();
}
aboutForm.append("\r\n\r\n版权所有 侵权必究\r\n");
aboutForm.addCommand(okCommand);
aboutForm.setCommandListener(new CommandListener(){
public void commandAction(Command c, Displayable arg1) {
if(c==okCommand)
{
Display.getDisplay(WirelessLinker.this).setCurrent(form);
}
}});
}
Display.getDisplay(this).setCurrent(aboutForm);
}
}
public static String getIP(String address)
{
String ip=null;
if(address.startsWith("datagram://"))
{
ip=address.substring(11);
}
int index=ip.lastIndexOf(':');
if(index>=0)
{
ip=ip.substring(0,index);
}
return ip;
}
// public static void log(String message)
// {
// try {
// FileConnection fc=(FileConnection)Connector.open("file:///E:/log.txt");
// if(fc.exists()==false)
// {
// fc.create();
// }
// OutputStream os=fc.openOutputStream();
//
// byte[] data=(message+"\n").getBytes("UTF-8");
// os.write(data,0, data.length);
// os.close();
// fc.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
abstract class TCPServer extends Thread{
protected ServerSocketConnection scn;
protected boolean runnable=true;
public TCPServer() throws IOException {
scn = (ServerSocketConnection) Connector.open("socket://:"+WirelessLinker.PORT);
}
public void run() {
while(runnable&&scn!=null)
{
try {
SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
doSocket(sc);
} catch (IOException e) {}
}
}
public abstract void doSocket(final SocketConnection sc);
public void close() throws IOException
{
if(this.scn!=null)
{
this.runnable=false;
this.scn.close();
}
System.out.println("TCPServer close");
}
}
class TCPClient{
public static SocketConnection connect(String ip) throws IOException
{
return (SocketConnection) Connector.open("socket://"+ip+":"+WirelessLinker.PORT);
}
}
class UDPClient extends Thread{
private UDPDatagramConnection dc;
private Vector packetQueue;
private boolean runnable=true;
public UDPClient() throws IOException {
dc = (UDPDatagramConnection) Connector.open("datagram://localhost:"+WirelessLinker.PORT);
this.packetQueue=new Vector();
}
public void run() {
Packet packet=null;
while(runnable)
{
synchronized (this.packetQueue) {
while(this.packetQueue.isEmpty())
{
System.out.println("PacketQueue is Empty");
this.packetQueue.notify();
try {
this.packetQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if(runnable==false)
return;
}
packet=(Packet) this.packetQueue.elementAt(0);
this.packetQueue.removeElementAt(0);
try {
send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private void send(Packet packet) throws IOException
{
Datagram dg=dc.newDatagram(packet.data,packet.data.length,"datagram://"+packet.ip+":"+WirelessLinker.PORT);
dc.send(dg);
}
public void send(byte[] data,String ip)
{
synchronized (this.packetQueue) {
this.packetQueue.addElement(new Packet(ip,data));
this.packetQueue.notify();
}
}
public void sendHi(String ip)
{
synchronized (this.packetQueue) {
this.packetQueue.addElement(new Packet(ip,new byte[]{WirelessLinker.COMMAND_HI}));
this.packetQueue.notify();
}
}
public void sendReply(String ip)
{
synchronized (this.packetQueue) {
this.packetQueue.addElement(new Packet(ip,new byte[]{WirelessLinker.COMMAND_REPLY}));
this.packetQueue.notify();
}
}
public void sendExit(String ip)
{
synchronized (this.packetQueue) {
this.packetQueue.addElement(new Packet(ip,new byte[]{WirelessLinker.COMMAND_QUIT}));
this.packetQueue.notify();
}
}
public void close() throws IOException
{
this.runnable=false;
synchronized (this.packetQueue) {
this.packetQueue.notify();
}
dc.close();
System.out.println("UDPClient close");
}
class Packet{
private String ip;
private byte[] data;
public Packet(String ip,byte[] data) {
this.ip=ip;
this.data=data;
}
}
}
abstract class UDPServer extends Thread{
private UDPDatagramConnection dc;
private boolean runnable=true;
public UDPServer() throws IOException {
dc = (UDPDatagramConnection) Connector.open("datagram://:6548");
}
public void run() {
try {
while(runnable==true)
{
Datagram dg = dc.newDatagram(100);
dc.receive(dg);
receive(dg);
}
}catch (IOException e) {}
}
public String getLocalAddress()
{
if(dc!=null)
try {
return dc.getLocalAddress();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public String getLocalAddressPrefix()
{
String localAddress=getLocalAddress();
if(localAddress==null)
return null;
int index=-1;
for(int i=localAddress.length()-1;i>0;i--)
{
if(localAddress.charAt(i)=='.')
{
index=i;
break;
}
}
if(index==-1)
return null;
return localAddress.substring(0,index)+".";
}
public String getLocalBroadcastAddress()
{
return getLocalAddressPrefix()+255;
}
public int getPort()
{
if(dc!=null)
try {
return dc.getLocalPort();
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
public void close() throws IOException
{
this.runnable=false;
this.interrupt();
this.dc.close();
System.out.println("UDPServer close");
}
public abstract void receive(Datagram dg);
}
class FileInfo{
private String fileName;
private long fileSize;
private String stringSize;
private FileConnection fileConnection;
public FileInfo(String fileName,long fileSize) {
this.fileName=fileName;
this.fileSize=fileSize;
}
public String getFileName() {
return fileName;
}
public long getFileSize() {
return fileSize;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
public FileConnection getFileConnection() {
return fileConnection;
}
public void setFileConnection(FileConnection fileConnection) {
this.fileConnection = fileConnection;
}
public String getStringFileSize()
{
if(this.stringSize==null)
this.stringSize=getStringSize(fileSize);
return this.stringSize;
}
public static String getStringSize(long size)
{
String stringSize;
float fileSize=(float)size;
if(fileSize>1073741824)
{
fileSize/=1073741824;
stringSize=format(fileSize,2)+"G";
}
else
{
if(fileSize>1048576)
{
fileSize/=1048576;
stringSize=format(fileSize,2)+"M";
}
else
{
if(fileSize>1024)
{
fileSize/=1024;
stringSize=format(fileSize,2)+"K";
}
else
{
stringSize=format(fileSize,2)+"B";
}
}
}
return stringSize;
}
/**
* 保留小数点后几位,不支持四舍五入
* @param number
* @param scale
* @return
*/
public static String format(double number,int scale)
{
return format(String.valueOf(number), scale);
}
/**
* 保留小数点后几位,不支持四舍五入
* @param number
* @param scale
* @return
*/
public static String format(String number,int scale)
{
if(number.startsWith("."))
number=0+number;
int index=number.indexOf('.');
if(index==-1||number.length()-index-1<scale)
{
StringBuffer buffer=new StringBuffer();
if(index==-1)
{
buffer.append(".");
}
for(int i=number.length()-index-1;i<scale;i++)
{
buffer.append("0");
}
return number.concat(buffer.toString());
}
else
{
return number.substring(0,index+scale+1);
}
}
public boolean equals(Object obj) {
if(obj instanceof FileInfo)
{
FileInfo info=(FileInfo)obj;
return fileName.equals(info.fileName)&&fileSize==info.fileSize;
}
return false;
}
}