今天有幸参加#移动者开发大会# ,也是我第二次参与这个活动了。随着智能机的普及,尤其是安卓千元的手机迅猛发展,2011年可以说事移动领域的积累期,2012年将会是蓬勃的发展期。各大厂商也在努力学习iphone的app store模式,努力搭建自己的平台,构建自己的生态圈,这也使得大量的资金涌入移动领域,造就了一大批移动创业先锋。
李开复说移动领域具有很强的先机优势(当然原话不是这个样子的),某个领域一旦被别人抢先进入,那么后来者很难超越,但是,深耕细作,努力打造一个好产品,步步为营,这一点也很重要,不要眼红那些靠宣传和营销走火的应用,毕竟不长久,做的不好,没吸引力,用户还是会走。这也是很多移动开发人员忽略的,今天做这个产品,明天做那个产品,很难做精做专。
另外一个想法一直萦绕在我的大脑里,就是一个对移动终端的一个小硬件的添加甚至可能会催生一个产业。比如 GPS硬件的添加,使得基于LBS的应用不断,社交,美食,导航,直接改变了人们的日常生活。再比如IPhone对三轴陀螺仪的加入,又使得人们在使用手机游戏的方式又很大改变。NFC的加入则有可能改变支付领域。大部分第三方软件(也是手机和系统厂商非常看重的开发者社群)都是围绕着这些小硬件开发的。
人们很强调软件的开发。但是软件受到硬件的限制。硬件是软件的基础。云端可以说是对手机的一个很大的延伸。但是,我们需要注意的一点是,苹果的成功固然是建立在其完善的生态圈上,但是不可或缺的是他对硬件的掌控。Iphone的手机游戏是很吸引人眼球的东东,除了基本的配置,如CPU,Ram等一开始比较强悍外,苹果对手机添加的3d陀螺仪,各种感应器也极大的催生了基于此类创意的开发。
所以 适当添加某种功能硬件,会极大出发相关软件应用的开发。
比如现在很多温度的软件通过定位在互联网查找相关的天气服务,再显示出来。其实很用户所在位置的相关温度差别极大。但是如果手机包含了感知温度的硬件,软件便可以直接获得用户一米之内的温度。这也会催生出某些软件应用。今天我看到一个很有趣的东西,是对IPhone的硬件扩展,辅之以相应的软件,那么用处是很大的。
这张图片外界的是一个某个感应硬件,里面的波形图是对硬件传来的电流脉冲的解析。这说明硬件和软件一样,都是可以无限扩张的。
对于移动领域的软件开发而言,什么时候进入都不会晚。计算机总是朝着便携小巧发展。先前的大型机,到后来的PC台式机,再到笔记本,然后到现在的手机终端。我一直认为现在的智能机就是计算机的延伸,是笔记本的下一代,目前很难想象还有比手机更小巧的(再小就挑战人类的眼睛了,或许是头戴式的,直接投入影像到你视网膜的某种产品),所以应该说很长一段时间人们将会停留在手机这个终端上。
链接:http://zxandroid.iteye.com/blog/419305
Unity3D客户端:
namespace LSocket.Net
{ /**
*
* @author feng侠,qq:313785443
* @date 2010-12-23
*
*/
// 描 述:封装c# socket数据传输协议
using UnityEngine;
using System;
using System.Net.Sockets;
using System.Net;
using System.Collections;
using System.Text;
using LSocket.Type;
using LSocket.cmd;
public class UnitySocket
{
public static Socket mSocket = null;
public UnitySocket()
{
}
public static void SocketConnection(string LocalIP, int LocalPort)
{
mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IPAddress ip = IPAddress.Parse(LocalIP);
IPEndPoint ipe = new IPEndPoint(ip, LocalPort);
mSocket.Connect(ipe);
Send("<!policy-file-request>");//the second connect.if it's not equals policy head,it will come in the main connect!
Send(CommandID.LOGIN);
Send("feng");
string s=ReceiveString(100);//从服务器端接受返回信息
MonoBehaviour.print(s.Length);
MonoBehaviour.print(s);
}
catch (Exception e)
{
//ErrLog.RecordErr(e, ModuleName, "AsySocket", "");
}
}
public static void Send(short data)
{
byte[] longth=TypeConvert.getBytes(data,false);
mSocket.Send(longth);
}
public static void Send(long data)
{
byte[] longth=TypeConvert.getBytes(data,false);
mSocket.Send(longth);
}
public static void Send(int data)
{
byte[] longth=TypeConvert.getBytes(data,false);
mSocket.Send(longth);
}
public static void Send(string data)
{
byte[] longth=Encoding.UTF8.GetBytes(data);
mSocket.Send(longth);
}
public static short ReceiveShort()
{
byte[] recvBytes = new byte[2];
mSocket.Receive(recvBytes,2,0);//从服务器端接受返回信息
short data=TypeConvert.getShort(recvBytes,true);
return data;
}
public static int ReceiveInt()
{
byte[] recvBytes = new byte[4];
mSocket.Receive(recvBytes,4,0);//从服务器端接受返回信息
int data=TypeConvert.getInt(recvBytes,true);
return data;
}
public static long ReceiveLong()
{
byte[] recvBytes = new byte[8];
mSocket.Receive(recvBytes,8,0);//从服务器端接受返回信息
long data=TypeConvert.getLong(recvBytes,true);
return data;
}
public static string ReceiveString(int length)
{
byte[] recvBytes = new byte[length];
mSocket.Receive(recvBytes,length,0);//从服务器端接受返回信息
string data=Encoding.UTF8.GetString(recvBytes);
return data;
}
}
}
namespace LSocket.cmd
{
public class CommandID
{
/** 错误消息命令 **/
public static int ERROR = 1000;
/** 登陆消息命令 **/
public static int LOGIN = 1001;
/** 退出消息命令 **/
public static int EXIT = 1002;
/** 获取pdb文件消息命令 **/
public static int GETPDB= 1003;
public static int GETPDB_AGAIN = 1006;
/** 其他用户进入消息命令 **/
public static int OTHER_USERS = 1004;
public static int ACCEPT=1005;
public CommandID()
{
}
}
}
namespace LSocket.Type
{
using UnityEngine;
using System.Collections;
public class TypeConvert
{
public TypeConvert()
{
}
public static byte[] getBytes(short s, bool asc)
{
byte[] buf = new byte[2];
if (asc)
{
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
else
{
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
return buf;
}
public static byte[] getBytes(int s, bool asc)
{
byte[] buf = new byte[4];
if (asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
return buf;
}
public static byte[] getBytes(long s, bool asc)
{
byte[] buf = new byte[8];
if (asc)
for (int i = buf.Length - 1; i >= 0; i--)
{
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.Length; i++)
{
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
return buf;
}
public static short getShort(byte[] buf, bool asc) {
if (buf == null) {
//throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 2) {
//throw new IllegalArgumentException("byte array size > 2 !");
}
short r = 0;
if (asc)
for (int i = buf.Length - 1; i >= 0; i--) {
r <<= 8;
r |= (short)(buf[i] & 0x00ff);
}
else
for (int i = 0; i < buf.Length; i++) {
r <<= 8;
r |= (short)(buf[i] & 0x00ff);
}
return r;
}
public static int getInt(byte[] buf, bool asc) {
if (buf == null) {
// throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 4) {
//throw new IllegalArgumentException("byte array size > 4 !");
}
int r = 0;
if (asc)
for (int i = buf.Length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
else
for (int i = 0; i < buf.Length; i++) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
return r;
}
public static long getLong(byte[] buf, bool asc) {
if (buf == null) {
//throw new IllegalArgumentException("byte array is null!");
}
if (buf.Length > 8) {
//throw new IllegalArgumentException("byte array size > 8 !");
}
long r = 0;
if (asc)
for (int i = buf.Length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
else
for (int i = 0; i < buf.Length; i++) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
return r;
}
}
}
Java服务器端:
package com.unity.socket;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
/**
*
* @author feng侠
* @date 2010-12-23
*
*/
public class ByteSocketServer
{
//存放所有用户位置的map
private HashMap<String,User> userMap;
private ByteArrayOutputStream byteOutput;
private DataOutputStream output;
public ByteSocketServer()
{
userMap = new HashMap<String, User>();
}
/**
* @param args
*/
public static void main(String[] args)
{
new ByteSocketServer().startServer();
}
public void startServer()
{
try
{
ServerSocket serverSocket = new ServerSocket(843);
System.out.println("服务器开启");
//LoadPDB loadPDB=new LoadPDB();
while(true)
{
//新建一个连接
Socket socket = serverSocket.accept();
System.out.println("有用户登陆进来了");
//启动一条新的线程
//new UserThreadHandler(socket,userMap).start();
//byte[] b=new byte[22];
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
// PrintWriter pw=new PrintWriter(socket.getOutputStream());
byteOutput = new ByteArrayOutputStream();
output = new DataOutputStream(byteOutput);
char[] by=new char[22];
br.read(by,0,22);
String head=new String(by);
//String scmd=new String(by);
//System.out.println("命令号字符串:" + scmd+"ok");
if(head.equals("<policy-file-request/>"))
{
output.writeBytes(SecurityXML.GetXml()+"\0");
DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
//编写数据的长度
// dataOutput.writeLong(bytes.length);
System.out.print(head);
dataOutput.write(byteOutput.toByteArray());
dataOutput.flush();
socket.close();
// pw.write(SecurityXML.GetXml()+"\0");
// pw.flush();
}
else
{
new LoadPDB(socket,userMap).start();
}
}
}
catch (Exception e)
{
System.out.println("服务器出现异常!" + e);
}
}
}
package com.unity.socket;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import com.pdb.AnalyzePDB;
import com.unity.socket.type.ConvertType;
public class LoadPDB extends Thread
{
/** 错误消息命令 **/
public static final int ERROR = 1000;
/** 登陆消息命令 **/
public static final int LOGIN = 1001;
/** 退出消息命令 **/
public static final int EXIT = 1002;
/**获取pdb文件消息命令 **/
public static final int GETFILE = 1003;
/** 其他用户进入消息命令 **/
public static final int OTHER_USERS = 1004;
public static final int ACCEPT=1005;
private Socket socket;
//存放所有用户位置的map
private HashMap<String,User> userMap;
private User user;
private ByteArrayOutputStream byteOutput;
private DataOutputStream output;
int count=0;
private boolean first=true;
public LoadPDB(Socket socket,HashMap<String,User> userMap) throws IOException
{
this.socket = socket;
this.userMap = userMap;
}
public void run()
{
try
{
DataInputStream input = new DataInputStream(socket.getInputStream());
//这里就是解析协议的部分
while(true)
{
//读出开头长度的short(2个字节)
int cmd=0;
byte[] b=new byte[4];
input.read(b);
//String cmd=new String(b);
cmd=ConvertType.getInt(b,true);
System.out.println("命令号:" + cmd);
//根据cmd的值不同,判断后续的内容是什么
switch(cmd)
{
case LOGIN:
//读取用户名
System.out.println("读取用户名:" );
byte[] nameBytes=new byte[4];
input.read(nameBytes);
String userName = new String(nameBytes);
user = new User();
user.setName(userName);
user.setSocket(socket);
//判断该用户是否存在
if(userMap.containsKey(userName))
{
//用户名重复,发送回客户端
}
else
{
System.out.println("有新用户进入:" + userName);
userMap.put(userName, user);
initOutput();
String sReturn="It's ok to connect to server!";
byte[] bb=sReturn.getBytes();
output.write(bb, 0, bb.length);
sendMessage(socket,byteOutput.toByteArray());
}
break;
case GETFILE:
//获取分子文件
//String name= input.readUTF();
initOutput();
//读出len之后,接着是读取short类型的cmd(2个字节)
byte[] bb=new byte[4];
input.read(bb);
int type=ConvertType.getInt(bb, true);
System.out.println(type);
if(type==0)
{
byte[] bid=new byte[4];
input.read(bid);
String sid=new String(bid);
System.out.println("enter!");
// System.out.print(bis.);
File file=new File("d:/pdb/"+sid+".pdb");
if(!file.exists())
{
URL url=new URL("http://www.pdb.org/pdb/download/downloadFile.do?fileFormat=pdb&compression=NO&structureId="+sid);
URLConnection urlconn = url.openConnection(); //
HttpURLConnection httpconn = (HttpURLConnection)urlconn;
System.out.print(httpconn.HTTP_OK);
//InputStream in=url.openStream();
//InputStreamReader reader=new InputStreamReader(in);
BufferedInputStream bis=new BufferedInputStream(urlconn.getInputStream());
int s;
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(file));
String str = "";
while((s=bis.read())!=-1)
{
// str=str+Integer.toString(s);
bos.write(s);
// System.out.print(s);
// System.out.print(s);
}
System.out.print("ok");
bos.flush();
bos.close();
bis.close();
}
int number=AnalyzePDB.getAtoms(file);
// count++;
//int number=AnalyzePDB.alist.size();
byte[] bNumber=ConvertType.getBytes(number, false);
//System.out.print( bNumber.length);
// System.out.println("why?");
// DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
//编写数据的长度
// dataOutput.writeLong(bytes.length);
System.out.print(number);
// byte[] b0=output.
output.write(bNumber);
//dataOutput.write(byteOutput.toByteArray());
//dataOutput.flush();
sendMessage(socket,byteOutput.toByteArray());
//sendAllUser(byteOutput.toByteArray());
}
else
{
String atoms=(String) AnalyzePDB.alist.get(type-1);
System.out.print(atoms.getBytes().length);
output.writeBytes(atoms);
sendMessage(socket,byteOutput.toByteArray());
Thread.sleep(500);
}
break;
case ACCEPT:
initOutput();
output.writeShort(ACCEPT);
output.writeUTF(user.getName());
String ss=input.readUTF();
output.writeUTF(ss);
sendAllUser(byteOutput.toByteArray());
break;
default :break;
}
}
}
catch (Exception e)
{
//异常处理,当有用户异常退出时,向其他用户发出退出命令
//删除出现异常的username
if(!userMap.isEmpty())
{
try
{
System.out.println("发送该用户退出命令");
userExit();
}
catch (Exception ee)
{
System.out.println("用户退出异常!ee:" + ee);
}
}
System.out.println("线程错误:");
}
}
private void userExit() throws Exception
{
userMap.remove(user.getName());
initOutput();
output.writeShort(EXIT);
output.writeUTF(user.getName());
sendAllUser(byteOutput.toByteArray());
}
//重新初始化2个新的output
private void initOutput()
{
byteOutput = new ByteArrayOutputStream();
output = new DataOutputStream(byteOutput);
}
public void sendAllUser(byte[] bytes) throws Exception
{
for(Iterator<User> it = userMap.values().iterator(); it.hasNext();)
{
sendMessage(it.next().getSocket(),bytes);
}
}
/**
* 发送数据到网络流
* @param socket
* @param bytes
* @throws Exception
*/
public void sendMessage(Socket socket,byte[] bytes) throws Exception
{
DataOutputStream dataOutput = new DataOutputStream(socket.getOutputStream());
//编写数据的长度
// dataOutput.writeLong(bytes.length);
//System.out.print(bytes.length);
dataOutput.write(bytes);
dataOutput.flush();
}
public void sendUser(byte[] bytes,String name) throws Exception
{
User user=userMap.get(name);
sendMessage(user.getSocket(),bytes);
}
}
package com.unity.socket;
import java.net.Socket;
public class User
{
private String name;
private Socket socket;
private short x;
private short y;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public Socket getSocket()
{
return socket;
}
public void setSocket(Socket socket)
{
this.socket = socket;
}
public short getX()
{
return x;
}
public void setX(short x)
{
this.x = x;
}
public short getY()
{
return y;
}
public void setY(short y)
{
this.y = y;
}
}
package com.unity.socket.type;
public class ConvertType
{
public ConvertType()
{
}
public final static byte[] getBytes(short s, boolean asc)
{
byte[] buf = new byte[2];
if (asc)
{
for (int i = buf.length - 1; i >= 0; i--)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
else
{
for (int i = 0; i < buf.length; i++)
{
buf[i] = (byte) (s & 0x00ff);
s >>= 8;
}
}
return buf;
}
public final static byte[] getBytes(int s, boolean asc) {
byte[] buf = new byte[4];
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (s & 0x000000ff);
s >>= 8;
}
return buf;
}
public final static byte[] getBytes(long s, boolean asc) {
byte[] buf = new byte[8];
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
else
for (int i = 0; i < buf.length; i++) {
buf[i] = (byte) (s & 0x00000000000000ff);
s >>= 8;
}
return buf;
}
public final static short getShort(byte[] buf, boolean asc)
{
if (buf == null)
{
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 2)
{
throw new IllegalArgumentException("byte array size > 2 !");
}
short r = 0;
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x00ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x00ff);
}
return r;
}
public final static int getInt(byte[] buf, boolean asc) {
if (buf == null) {
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 4) {
throw new IllegalArgumentException("byte array size > 4 !");
}
int r = 0;
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x000000ff);
}
return r;
}
public final static long getLong(byte[] buf, boolean asc) {
if (buf == null) {
throw new IllegalArgumentException("byte array is null!");
}
if (buf.length > 8) {
throw new IllegalArgumentException("byte array size > 8 !");
}
long r = 0;
if (asc)
for (int i = buf.length - 1; i >= 0; i--) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
else
for (int i = 0; i < buf.length; i++) {
r <<= 8;
r |= (buf[i] & 0x00000000000000ff);
}
return r;
}
}