android之socket编程实例

注意点:注册访问的网络权限;android中UI线程不能有访问网络的操作,否则会报android.os.NetworkOnMainThreadException的异常

    <uses-permission 
        android:name="android.permission.INTERNET"/>

实例一

客户端


package com.android.xiong.simplesocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
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 {
	Socket socket = null;
	String buffer = "";
	TextView txt1;
	Button send;
	EditText ed1;
	String geted1;
	public Handler myHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == 0x11) {
				Bundle bundle = msg.getData();
				txt1.append("server:"+bundle.getString("msg")+"\n");
			}
		}

	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		txt1 = (TextView) findViewById(R.id.txt1);
		send = (Button) findViewById(R.id.send);
		ed1 = (EditText) findViewById(R.id.ed1);
		send.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				geted1 = ed1.getText().toString();
				txt1.append("client:"+geted1+"\n");
				//启动线程 向服务器发送和接收信息
				new MyThread(geted1).start();
			}
		});

	}

	class MyThread extends Thread {

		public String txt1;

		public MyThread(String str) {
			txt1 = str;
		}

		@Override
		public void run() {
			//定义消息
			Message msg = new Message();
			msg.what = 0x11;
			Bundle bundle = new Bundle();
			bundle.clear();
			try {
				//连接服务器 并设置连接超时为5秒
				socket = new Socket();
				socket.connect(new InetSocketAddress("1.1.9.30", 30000), 5000);
				//获取输入输出流
				OutputStream ou = socket.getOutputStream();
				BufferedReader bff = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				//读取发来服务器信息
				String line = null;
				buffer="";
				while ((line = bff.readLine()) != null) {
					buffer = line + buffer;
				}
				
				//向服务器发送信息
				ou.write("android 客户端".getBytes("gbk"));
				ou.flush();
				bundle.putString("msg", buffer.toString());
				msg.setData(bundle);
				//发送消息 修改UI线程中的组件
				myHandler.sendMessage(msg);
				//关闭各种输入输出流
				bff.close();
				ou.close();
				socket.close();
			} catch (SocketTimeoutException aa) {
				//连接超时 在UI界面显示消息
				bundle.putString("msg", "服务器连接失败!请检查网络是否打开");
				msg.setData(bundle);
				//发送消息 修改UI线程中的组件
				myHandler.sendMessage(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText 
        android:id="@+id/ed1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="给服务器发送信息"/>
    <Button 
        android:id="@+id/send"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/ed1"
        android:text="发送"/>
    <TextView 
        android:id="@+id/txt1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/send"/>
    
    


</RelativeLayout>

服务端

package com.android.net;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class AndroidService {


	public static void main(String[] args) throws IOException {
		ServerSocket serivce = new ServerSocket(30000);
		while (true) {
			//等待客户端连接
			Socket socket = serivce.accept();
			new Thread(new AndroidRunable(socket)).start();
		}
	}

}

package com.android.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class AndroidRunable implements Runnable {

	Socket socket = null;

	public AndroidRunable(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// 向android客户端输出hello worild
		String line = null;
		InputStream input;
		OutputStream output;
		String str = "hello world!";
		try {
			//向客户端发送信息
			output = socket.getOutputStream();
			input = socket.getInputStream();
			BufferedReader bff = new BufferedReader(
					new InputStreamReader(input));
			output.write(str.getBytes("gbk"));
			output.flush();
			//半关闭socket  
			socket.shutdownOutput();
			//获取客户端的信息
			while ((line = bff.readLine()) != null) {
				System.out.print(line);
			}
			//关闭输入输出流
			output.close();
			bff.close();
			input.close();
			socket.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}

实例二

客户端

package com.android.xiong.sockettwotest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
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 {

	// 定义界面上的两个文本框
	EditText input;
	TextView show;
	// 定义界面上的一个按钮
	Button send;
	Handler handler;
	// 定义与服务器通信的子线程
	ClientThread clientThread;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		input = (EditText) findViewById(R.id.input);
		show = (TextView) findViewById(R.id.show);
		send = (Button) findViewById(R.id.send);
		handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				// 如果消息来自子线程
				if (msg.what == 0x123) {
					// 将读取的内容追加显示在文本框中
					show.append("\n" + msg.obj.toString());
				}
			}
		};
		clientThread = new ClientThread(handler);
		// 客户端启动ClientThread线程创建网络连接、读取来自服务器的数据
		new Thread(clientThread).start();
		send.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				try {
					// 当用户按下按钮之后,将用户输入的数据封装成Message
					// 然后发送给子线程Handler
					Message msg = new Message();
					msg.what = 0x345;
					msg.obj = input.getText().toString();
					clientThread.revHandler.sendMessage(msg);
					input.setText("");

				} catch (Exception e) {

				}
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

package com.android.xiong.sockettwotest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

public class ClientThread implements Runnable {
	private Socket s;
	// 定义向UI线程发送消息的Handler对象
	Handler handler;
	// 定义接收UI线程的Handler对象
	Handler revHandler;
	// 该线程处理Socket所对用的输入输出流
	BufferedReader br = null;
	OutputStream os = null;

	public ClientThread(Handler handler) {
		this.handler = handler;
	}

	@Override
	public void run() {
		s = new Socket();
		try {
			s.connect(new InetSocketAddress("1.1.9.30", 3000), 5000);
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			os = s.getOutputStream();
			// 启动一条子线程来读取服务器相应的数据
			new Thread() {

				@Override
				public void run() {
					String content = null;
					// 不断的读取Socket输入流的内容
					try {
						while ((content = br.readLine()) != null) {
							// 每当读取到来自服务器的数据之后,发送的消息通知程序
							// 界面显示该数据
							Message msg = new Message();
							msg.what = 0x123;
							msg.obj = content;
							handler.sendMessage(msg);
						}
					} catch (IOException io) {
						io.printStackTrace();
					}
				}

			}.start();
			// 为当前线程初始化Looper
			Looper.prepare();
			// 创建revHandler对象
			revHandler = new Handler() {

				@Override
				public void handleMessage(Message msg) {
					// 接收到UI线程的中用户输入的数据
					if (msg.what == 0x345) {
						// 将用户在文本框输入的内容写入网络
						try {
							os.write((msg.obj.toString() + "\r\n")
									.getBytes("gbk"));
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}

			}; 
			// 启动Looper
			Looper.loop();

		} catch (SocketTimeoutException e) {
			Message msg = new Message();
			msg.what = 0x123;
			msg.obj = "网络连接超时!";
			handler.sendMessage(msg);
		} catch (IOException io) {
			io.printStackTrace();
		}

	}
}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/input" />
    <Button 
        android:id="@+id/send"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/send"
        android:layout_below="@id/input"/>
    <TextView 
        android:id="@+id/show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/send"/>

</RelativeLayout>

服务端


package com.android.net;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class MyService {

	// 定义保存所有的Socket
	public static List<Socket> socketList = new ArrayList<Socket>();

	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(3000);
		while(true){
			Socket s=server.accept();
			socketList.add(s);
			//每当客户端连接之后启动一条ServerThread线程为该客户端服务
			new Thread(new ServiceThreada(s)).start();
			
		}
	}

}


package com.android.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class ServiceThreada implements Runnable {

	// 定义当前线程处理的Socket
	Socket s = null;
	// 该线程所处理的Socket所对应的输入流
	BufferedReader br = null;

	public ServiceThreada(Socket s) {
		this.s = s;
		try {
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {

		String content = null;
		//采用循环不断的从Socket中读取客户端发送过来的数据
		while((content=readFromClient())!=null){
			//遍历socketList中的每个Socket
			//将读取到的内容每个向Socket发送一次
			for(Socket s:MyService.socketList){
				OutputStream os;
				try {
					os = s.getOutputStream();
					os.write((content+"\n").getBytes("gbk"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
			}
		}

	}

	// 定义读取客户端的信息
	public String readFromClient() {
		try {
			return br.readLine();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页