Git Product home page Git Product logo

android_socket_client's Introduction

##1.概述 ###1.1最终效果 如果android设备连接了网络,则通过android的客服端程序能够使这几台设备间相互交流,相当于一个聊天室 ###1.2数据流程 手机通过socket向服务器发送数据,服务器接收到后分别发送给除接收端外的其他接入对象。呃。。。就这么简单

接下来单独讲下服务器和客服端的实现,具体代码主要参考至极客学院 ##2.服务器 ###2.1结构 这个程序主要是扔到服务器上去转发接收到的数据。我仅仅单纯的写了一个socket方式的消息接收和转发。总计4个java文件。 MyserverSocket:主线程 ServerListener:子线程A,用于阻塞等待客服端的连接,并且对接 入的客服端再开启一个线程B。 ChatSocket:子线程B的具体要做的事,接收数据,发送数据 ChatManager:多客服端子线程的管理,里面封装了3个方法,添加一个对象,删除一个对象,将信息广播。 ###2.2流程 程序入口为MyserverSocket

package com.serverSocket.main;

//2016/3/5  lissettecarlr
//服务器程序,连接服务器后会接收到welcome
//这是一个socket服务器程序的入口,如果从一个客服端得到消息,它将转发给其他客服端

public class MyserverSocket {

	public static void main(String[] args) {
		 new ServerListener().start(); //建立实时监听客服端
	}

}

由于socket监听会阻塞线程,所以对其单独建立一个线程监听。 ServerListener

package com.serverSocket.main;

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

import javax.swing.JOptionPane;


//该类用于等待客服端连接
public class ServerListener extends Thread {
	@Override
	public void run() {
		try {
			ServerSocket serverSocket = new ServerSocket(23456); //端口
			while(true){
				//每当有一个客服端连接就有一个socket
				Socket socket =  serverSocket.accept();//阻塞
//				JOptionPane.showMessageDialog(null, "有客服端连接到本地的23457端口");
				System.out.println("有客服端链接-------");
				ChatSocket cs = new ChatSocket(socket);//新线程
				cs.start();         
 	            ChatManager.getChatManager().add(cs);		
			}
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
}

每当有一个新的客服端接入,就建立一个socket 对象,并且传入一个新的线程,再将他加入到一个对象表中。之后进入socket对象线程。

	public void print(String out)
	{
        //获得输出流
        OutputStream os;
		try {
			os = socket.getOutputStream();
	        PrintWriter pw=new PrintWriter(os);      
            pw.write(out);  
            pw.flush(); 
            
		} catch (IOException e) {
			ChatManager.getChatManager().remove(this);; 
			e.printStackTrace();
		}  

	}

这次封装的发送方法 下面是run方法,用于将接收到的数据转发出去 这里写图片描述 至此流程就结束了 还有一个ChatManager是一个工具,他用来保存管理各个接入对象

package com.serverSocket.main;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Vector;

//该类用于多个socket之间通信管理
public class ChatManager {
	
	private ChatManager(){}
	private static final ChatManager cm = new ChatManager();
	public static ChatManager getChatManager() {
		return cm;
	}
	
	Vector<ChatSocket> vector = new Vector<ChatSocket>();
	
	//为集合添加一个新的socket对象
	public void add(ChatSocket cs) {
		vector.add(cs);
	}
	
	public void remove(ChatSocket cs) {
		vector.remove(cs);
	}
	
	//首先将自己传递进来,在传入一个发送的信息
	public void publish(ChatSocket cs,String out) {
		for (int i = 0; i < vector.size(); i++) {
			ChatSocket csChatSocket = vector.get(i); //获取循环中第I个对象
			if (!cs.equals(csChatSocket)) { //如果不是当前
				csChatSocket.print(out);
			}
		}
	}
}

以上是服务器的所有代码,至于如何放到服务器上去运行,看我之前的帖子吧。

##3.android端 这里不会贴出所有代码,太长啦,就讲讲关键的部分吧。程序虽然有各种BUG,但是主要通信功能没问题,这里只是一个测试程序,之后会修改的 ###3.1布局 这里写图片描述 由3个button、2个EditText、2个textView的简单布局 ###3.2事件 我仅仅写了一个activity。 protected void onCreate(Bundle savedInstanceState)中主要写三个按键的点击事件。 这是连接的点击事件(仅仅是点击事件里面的内容):

public void connect() {
AsyncReadTask asyncReadTask = new AsyncReadTask();  asyncReadTask.execute(ip.getText().toString().trim());
    }


    private final class AsyncReadTask extends AsyncTask<String, String, String>{
        @Override
        protected String doInBackground(String... params) {  //由线程池开启新线程执行该函数中的内容
            try {
                socket = new Socket(params[0], 23456);
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                publishProgress("与服务器连接成功");
                flag = true;
            } catch (UnknownHostException e1) {
                Toast.makeText(getApplicationContext(), "无法建立链接", Toast.LENGTH_SHORT).show();
                flag =false ;
            } catch (IOException e1) {
                Toast.makeText(getApplicationContext(), "无法建立链接", Toast.LENGTH_SHORT).show();
                flag =false;
            }
            try {
                String line;
                while ((line = reader.readLine())!= null) {
                    publishProgress(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
        }

        @Override
        protected void onPostExecute(String result) {  //此处UI更新

        }

        @Override
        protected void onProgressUpdate(String... values) {    //数据由doInBackground返回过来
            if (values[0].equals("与服务器连接成功")) {
            }
            text.append("获得消息:"+values[0]+"\n");
            super.onProgressUpdate(values);
        }
    }

之后是断开的点击事件:

       close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    socket.close();
                    flag = false;
                    statue.setText("连接断开");
                } catch (IOException e) {
                    Toast.makeText(getApplicationContext(), "关闭失败", Toast.LENGTH_SHORT).show();
                }
            }
        });

最后是发送按键:


    public void send() {
        try {
            text.append("发送消息:"+editText.getText().toString()+"\n");
            writer.write(editText.getText().toString()+"\n");
            writer.flush();
            editText.setText("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

###3.3流程 在点击连接后,会读取IP对其建立socket对象,这里是另起的一个线程进行的,建立完对象后,在建立输入输出流,并且等待接收数据。当点击发送按钮时触发send事件,不会影响接收线程。

##4.测试 ###4.1第一步 首先将java程序运行至服务器。 我的系统是cenos于是就在文件目录下输入 java -jar XX.jar,这是前台运行,后台运行则输入nohup java -jar XX.jar & 后 在输入exit退出。 (如果发现端口被占用,则首先输入netstat -tln 查看端口占用情况,之后lsof -i :8083 看是那个程序占用了端口,在使用kill -9 进程ID杀死他) ###4.2第二步 你可以使用两个android手机,笔者只有一个,于是就在开启一个虚拟机就好了。 首先输入你服务器的IP地址,点击连接(这里有一个BUG,第一次点击断开会闪退 - -||) 这里写图片描述 这时消息显示区域会受到消息: 这里写图片描述 另外一台设备重复一遍后,随便使用一台设备在发送区域输入文字,点击发送,你将会在另外一台设备看到该文字。我这里将自己发送的前标为"发送消息",从服务器得到数据我标为了"获得数据" ##5.相关下载 服务器jar包和apk包下载 eclipse服务器程序下载 android程序下载

android_socket_client's People

Contributors

lissettecarlr avatar

Watchers

 avatar

Forkers

geekgarry

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.