前期准备:我的是Linux Mint操作系统(总之折腾的过程中怀疑过是不是系统的问题),首先是要创建wifi热点给android手机使用,这个时候笔记本作为通信的服务器端,android手机作为客户端,通过socket进行通信。
1.在eclipse下写好服务器端的代码,包括监听的端口好,客户端的IP地址获取,发送的数据处理等,这里涉及到J2EE的环境配置,有时间我在写下,这个代码是直接百度到的,能用:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class Test { private ServerSocket server; private Socket client; private BufferedReader in; private PrintWriter out; public Test() { try { server = new ServerSocket(9400); while (true) { System.out.println("start!"); // 获得客户端连接 client = server.accept(); // 获得客户端的IP和端口 String remoteIP = client.getInetAddress().getHostAddress(); int remotePort = client.getLocalPort(); System.out.println("A client connected. IP:" + remoteIP + ", Port: " + remotePort); System.out.println(); // 获得 client 端的输入输出流,为进行交互做准备 in = new BufferedReader(new InputStreamReader( client.getInputStream())); out = new PrintWriter(client.getOutputStream(), false); // 获得 client 端发送的数据 String tmp = in.readLine(); // String content = new String(tmp.getBytes("utf-8")); System.out.println("Client message is: " + tmp); // 向 client 端发送响应数据 out.println("Your message has been received successfully!."); // 关闭各个流 out.close(); in.close(); // server.close(); } } catch (Exception e) { // 发送响应,接收失败 System.out.println(e.toString()); out.println("Receive Error!"); } } public static void main(String[] args) { new Test(); } }
代码看起来也不是太难,关键是Java EE的使用,尤其是服务器的配置,(配置教程涉及到tomcat的配置,以及服务器的建立),
Project name随便写好了,然后next---->next,需要把Generate web.xml deployment descriptor勾选上。注意:
Java Resources 下的src文件夹下里面放的是相关的类,这个类写完之后还在Webcontent文件夹--->WEB-INF文件夹下的web.xml里面配置:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>TomcatTest</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Test</servlet-name> <servlet-class>Test</servlet-class> </servlet> <servlet-mapping> <servlet-name>Test</servlet-name> <url-pattern></url-pattern> </servlet-mapping> </web-app>
到这里你可以运行你的服务端,选中项目,右击选中Run as--->Run on server,到此你的网站基本上就发布成功了,在你的手机的浏览器中输入你PC端的IP地址,注意端口号是9400,比如我之前测试的用是的10.3.19.26:9400,就可以看到服务端返回的信息。
2.android端的程序比较简单,但是一开始的时候怎么都不能成功运行,最后发现的两个问题a.权限没有加,b.自从android3.0以后,android的运行机制不容许在主线程中使用网络的相关操作
我的值加了这几个权限,貌似也能够运行起来,呵呵:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
第二个问题,网上的一些代码太坑了,明明都是有问题,也不知道修改,下面写的很简单,没有图形界面,
package com.example.client; import java.io.IOException; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { private Button btnConnect, btnSend; private Socket socket; private PrintStream output; private EditText editSend; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnConnect = (Button) findViewById(R.id.button1); btnSend = (Button) findViewById(R.id.button2); editSend = (EditText) findViewById(R.id.editText1); btnConnect.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(runnable).start();//开启线程 } }); btnSend.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub sendMessage(editSend.getText().toString()); } }); } Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub initClientSocket(); } }; public void initClientSocket() { try { EditText edit_ip = (EditText) MainActivity.this.findViewById(R.id.editText2); String ip = edit_ip.getText().toString().trim(); socket = new Socket("10.3.19.26", 9400); output = new PrintStream(socket.getOutputStream(), true, "gbk"); } catch (UnknownHostException e) { // TODO Auto-generated catch block Toast.makeText(MainActivity.this, "请检查端口号是否为服务器IP", Toast.LENGTH_LONG).show(); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block Toast.makeText(MainActivity.this, "服务器未开启", Toast.LENGTH_LONG) .show(); e.printStackTrace(); } output.println("this is the message from client"); } private void sendMessage(String str) { output.println(str); } public void closeSocket() { try { output.close(); socket.close(); } catch (IOException e) { System.out.println("error"+e); } } }
基本上控件只有一个按钮,其他的都是没有用的,在按钮的监听器里面写的方法,就是使用Runable开启一个线程,在runable的方法中调用initClientSocket()方法,你会发现,里连接的代码很简单,我连接成功后就使用
output.println("this is the message from client");
这个就是返回给服务器的信息,一开始放在另一个按钮中的,但是考虑到上述的问题,还是直接在线程中发送(我测试过,在UI线程中不能使用这个方法,发送完了也没有反应)最终的服务器端接受的数据情况如下:
从下午到晚上总算弄完了2015-05-18 22:11:21,有时间把相关的配置弄下。