//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();
}
}
}