java/android的Socket&&ServerSocket

今晚我估计真的是闲得没事干了, 调了一晚上的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();
	}
}

毕!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值