今晚我估计真的是闲得没事干了, 调了一晚上的Socket和ServerSocket, 最后写出了一个客户端和一个服务器
基本框架类BaseFrame.java, 之所以写这么一个类, 是因为客户端和服务器有很多代码是相同的, 没必要每次都打一遍.
发送和接收数据都是另开一个线程进行的
import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JTextArea;
public class BaseFrame {
//设置时间格式
static protected SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//从sc上读取数据, 显示到ta上
static protected void readData(final Socket sc, final JTextArea ta){
new Thread(new Runnable(){
@Override
public void run() {
try{
BufferedReader in = new BufferedReader(
new InputStreamReader(sc.getInputStream()));
String line = in.readLine();
ta.append(df.format(new Date())+": "+line+"\n");
in.close();
sc.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
//从sc发送数据, 内容是str
static protected void sendData(final Socket sc, final String str){
new Thread(new Runnable(){
@Override
public void run() {
try{
BufferedWriter out=new BufferedWriter(
new OutputStreamWriter(sc.getOutputStream()));
out.write(str);
out.close();
sc.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
服务器代码Server.java
import java.net.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;;
class Server extends BaseFrame{
public static void main(String[] args){
JFrame jf=new JFrame();
final JTextArea ta=new JTextArea(15,28);
//设置程序界面
ta.setEditable(false);
jf.add(new JScrollPane(ta));
jf.pack();
jf.setBounds(400, 100, 330, 410);
jf.setVisible(true);
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ee) {
System.exit(0);//exit会自动回收资源, 关闭ServerSocket
}
});
//服务器等待客户端的数据
try{
ServerSocket ss=new ServerSocket(2008);
while (true){
Socket sc;
//先接收数据
sc=ss.accept();
readData(sc,ta);
//再发送数据,响应客户端
sc=ss.accept();
sendData(sc, "message from server\n");
}
}
catch (Exception e){
ta.append(e.toString()+"\n");
}
}
}
客户端代码Client.java
import java.net.*;
import java.awt.BorderLayout;
import java.awt.event.*;
import javax.swing.*;
class Client extends BaseFrame{
public static void main(String[] args){
JFrame jf=new JFrame();
final JTextArea ta=new JTextArea(15,28);
JButton bu=new JButton("communicate with server");
//设置程序界面
ta.setEditable(false);
jf.add(new JScrollPane(ta));
jf.add(bu, BorderLayout.SOUTH);
jf.pack();
jf.setBounds(400, 100, 330, 410);
jf.setVisible(true);
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ee) {
System.exit(0);
}
});
//添加按键监听器
bu.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
Socket sc;
//先发送数据
sc=new Socket("127.0.0.1",2008);
sendData(sc,"message from client\n");
//再接收数据, 接收服务器的反馈
sc=new Socket("127.0.0.1",2008);
readData(sc,ta);
}
catch(Exception e){
ta.append(e.toString()+"\n");
}
}
});
}
}
先运行服务器, 再运行客户端, 运行结果如下(左边2个客户端+右边1个服务器):
然后, 就是进行手机和电脑之间的通信了, 因为不会打洞和nat技术, 所以目前手机和电脑的通信仅限于局域网
不废话了, 先上图(左边是手机, 右边是运行着的Server), 按手机apk上的获取键就可以互发数据了
安卓app的java源代码为(思路跟Client.java的差不多):
package com.example.myapp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
Handler hd=new Handler();
static String str;
static protected SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//在Android系统版本>2.3的时候,系统强制不能在主线程中访问网络
//Handler.post方法中Runnable不是新开的线程
//所以加入下面代码判断不同版本,进行不同处理
if (Integer.valueOf(VERSION.SDK) > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
}
Button bu1=(Button)findViewById(R.id.bu1);
bu1.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
hd.post(thrun);
}
});
}
private void setTextFromInternet(){
String path=((EditText)findViewById(R.id.et)).getText().toString();
TextView tv=(TextView)findViewById(R.id.tv);
try{
Socket sc;
//先发送数据
sc=new Socket(path,2008);
sendData(sc,"message from phone\n");
//再接收数据, 接收服务器的反馈
sc=new Socket(path,2008);
readData(sc);
while (str==null);
tv.append("\n"+str);
}
catch (Exception e){
tv.append(e.toString());
}
}
Runnable thrun=new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
setTextFromInternet();
}
};
static protected void readData(final Socket sc){
new Thread(new Runnable(){
@Override
public void run() {
try{
BufferedReader in = new BufferedReader(
new InputStreamReader(sc.getInputStream()));
String line = in.readLine();
str=df.format(new Date()).toString()+": "+line;
in.close();
sc.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
//从sc发送数据, 内容是str
static protected void sendData(final Socket sc, final String str){
new Thread(new Runnable(){
@Override
public void run() {
try{
BufferedWriter out=new BufferedWriter(
new OutputStreamWriter(sc.getOutputStream()));
out.write(str);
out.close();
sc.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
毕!