//////////////////////////2016/01/31///////////////////////
////////////////////////by XBW////////////////////////////
//////////////////////环境 eclipse///////////////////////
终于搞到安卓通信了,用了socket套接字进行了一下小测试,把安卓客户端跟java服务器端代码共享了;
安卓4.0以后socket通信时,socket的建立连接等不能直接在主进程中,需要新开进程。于是又学习了一下线程,不过简单的socket连接测试线程用的还不是很明显,因为我没写UI,UI也不用更新;
先看一下安卓客户端的代码;
布局没写,直接用了新建的activity_main.xml,
config.java为配置项,
package Client_Config; public class config { public static String ip="139.129.40.202"; public static int port=3333; }
MainActivity.java中只开了线程
package com.example.socket; import public_class.ClientThread; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private ClientThread clientThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { clientThread=new ClientThread(); clientThread.start(); return true; } return super.onOptionsItemSelected(item); } }
ClientThread.java为处理线程
package public_class; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import com.example.socket.MainActivity; import Client_Config.config; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; public class ClientThread extends Thread{ private SocketAddress socketAddress; private Socket socket; void connect() { socketAddress=new InetSocketAddress(config.ip, config.port); socket=new Socket(); try { socket.connect(socketAddress,5000); Log.w("反馈:","连接成功"); }catch(IOException e) { Log.w("反馈:","连接超时"); } } public void run() { connect(); } }
最后需要配置一下AndroidManifest.xml的权限;
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.socket" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
下面是java服务器端代码
Client.java
package server; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.SocketException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class Client implements Runnable { private Socket s = null; private InputStream ips =null; private boolean bConnected = false; private String sendmsg=null; private String getnameString=null; public List<Map<Object, Object>> getList; public Client (Socket s) { this.s = s; try { ips = s.getInputStream(); bConnected = true; } catch(IOException e) { e.printStackTrace(); } } public void run() { try { while (bConnected) { InputStreamReader ipsr = new InputStreamReader(ips); BufferedReader br = new BufferedReader(ipsr); String ss = ""; while((ss = br.readLine()) != null) System.out.println(ss); } } catch (SocketException e) { System.out.println("client is closed!"); Myserver.rizhi(" "+(config.RL++)+". "+"client is closed!"); Myserver.clients.remove(this); } catch (EOFException e) { System.out.println("client is closed!"); Myserver.rizhi(" "+(config.RL++)+". "+"client is closed!"); Myserver.clients.remove(this); } catch (IOException e) { e.printStackTrace(); } finally { try { if (s != null) { s.close(); ips.close(); } else System.out.println("与服务器断开连接"); } catch (IOException e) { e.printStackTrace(); } } } }
config.java
package server; public class config { //日志记录 public static int RL=0; }
Myserver.java
package server; import java.awt.AWTException; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; public class Myserver { public static boolean Server_judge=false; public static boolean Server_started=false; public static ServerSocket socket = null; public static String path=""; public static List<Client> clients = new ArrayList<Client>(); public static void main(String [] args) { path = new Myserver().getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); try { path = URLDecoder.decode(path,"utf-8"); } catch (UnsupportedEncodingException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } if (path.endsWith(".jar")) path = path.substring(0, path.lastIndexOf("/") + 1); while(!Server_judge) { String inputport = JOptionPane.showInputDialog("请输入该服务器使用的端口:3333"); int port = Integer.parseInt(inputport); new Myserver().start(port); if(Server_started) { hide(); jiankong(); } } } public void start(int port) { try { socket = new ServerSocket(port); System.out.println("服务器启动成功"); JOptionPane.showMessageDialog(null, "服务器启动成功"); Server_started = true; Server_judge=true; } catch (BindException e) { System.out.println(" 端口已经被占用"); JOptionPane.showMessageDialog(null, "端口已经被占用"); } catch (IOException e) { e.printStackTrace(); } } public static void hide() { if(SystemTray.isSupported()){//判断当前平台是否支持托盘功能 //创建托盘实例 SystemTray tray = SystemTray.getSystemTray(); //创建托盘图标:1.显示图标Image 2.停留提示text 3.弹出菜单popupMenu 4.创建托盘图标实例 //1.创建Image图像 Image image = Toolkit.getDefaultToolkit().getImage(path+"//images//icon.png"); //2.停留提示text String text = "聊天服务器"; //3.弹出菜单popupMenu PopupMenu popMenu = new PopupMenu(); MenuItem itmOpen = new MenuItem("打开日志"); itmOpen.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { try { String basepath=path+"Server_Log.txt"; Runtime runtime= Runtime.getRuntime(); runtime.exec("notepad.exe "+basepath.substring(1)); }catch(IOException e1) { e1.printStackTrace(); JOptionPane.showMessageDialog(null, "日志不存在或路径错误,应在"+path+"文件中建立Server_Log.txt"); } } }); MenuItem itmExit = new MenuItem("退出"); itmExit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.exit(0); } }); popMenu.add(itmOpen); popMenu.add(itmExit); //创建托盘图标 TrayIcon trayIcon = new TrayIcon(image,text,popMenu); //将托盘图标加到托盘上 try { tray.add(trayIcon); } catch (AWTException e1) { e1.printStackTrace(); } } } public static void jiankong() { try { while (Server_started) { Socket s = socket.accept(); Client c = new Client (s); System.out.println("一个用户连接进来"); rizhi(" "+(config.RL++)+". "+"一个用户连接进来"); new Thread(c).start(); clients.add(c); } } catch (IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void rizhi(String s) { String toAppend = s; try { // 打开一个随机访问文件流,按读写方式 RandomAccessFile randomFile = new RandomAccessFile(path+"//Server_Log.txt", "rw"); // 文件长度,字节数 long fileLength = randomFile.length(); // 将写文件指针移到文件尾。 randomFile.seek(fileLength); String c=new String(toAppend.getBytes("GBK"),"ISO8859_1"); randomFile.writeBytes(c+"\r\n"); randomFile.close(); } catch (IOException e) { e.printStackTrace(); } } }
源码下载