Android中基于Socket的网络通信

来源:互联网 发布:激战2捏脸数据 编辑:程序博客网 时间:2024/04/25 17:07

Socket介绍


1.什么是Socket?

这里写图片描述

2.Socket链接的创建过程

    1.服务器监听    2.客户端发出请求    3.建立链接    4.通信

3.Socket特点

    1.Socket基于TCP链接,数据有保障    2.Socket适用于建立长时间链接    3.Socket编程通常应用于即时通讯

ServerSocket 基本使用Demo


基本使用Demo -代码

package com.lhy.testmyserversocket;import java.io.IOException;import java.net.ServerSocket;import javax.swing.JOptionPane;public class Demo {    /**     * @param args     */    public static void main(String[] args) {        try {            //当前socket监听的端口  端口限制 1-65535             ServerSocket server = new ServerSocket(12345);            //1. 开始监听本机12345端口              server.accept(); //accept 是阻塞方法,会阻塞线程(所以建议在主线程中使用)            //2.弹出提示框            JOptionPane.showMessageDialog(null, "有客户端连接到了本机的12345端口");            //3.运行程序,打开一个浏览器输入 127.0.0.1:12345        } catch (IOException e) {            e.printStackTrace();        }     }}

运行结果

这里写图片描述

ServerSocket 进阶使用Demo - 建立聊天服务器


使用的类和类说明

              Main -主函数,执行类。    ServerListener -服务器 监听端口类         ChatSocket -客户端功能类       ChatManager -客户端管理类
Main 类
package com.lhy.testmyserversocket;public class Main {    /**     * @param args     */    public static void main(String[] args) {        new ServerListener().start();    }}
ServerListener 类
package com.lhy.testmyserversocket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import javax.swing.JOptionPane;public class ServerListener extends Thread {    //重写 thread run     @Override    public void run() {        try {            //当前socket监听的端口  端口限制 1-65535             ServerSocket server = new ServerSocket(12345);            while(true)            {                //1. 开始监听本机12345端口                  Socket socket = server.accept(); //accept 是阻塞方法,在没有访问的时候一直监听阻塞,只有在有访问的时候才会释放线程                //2.弹出提示框                JOptionPane.showMessageDialog(null, "有客户端连接到了本机的12345端口");                //3.将socket传递给新的线程                ChatSocket cs = new ChatSocket(socket);                cs.start();                ChatManager.getChatManager().add(cs); //当前socket对象添加的聊天管理器中            }        } catch (IOException e) {            e.printStackTrace();        }     }}
ChatSocket
package com.lhy.testmyserversocket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.net.Socket;public class ChatSocket extends Thread{    //声明socket对象  ,接收传入的值    Socket socket;    //创建构造方法 传入Socket参数    public ChatSocket(Socket s) {        this.socket = s;    }    //输入方法    public void out (String out)    {        try {            //向服务器发送字节            socket.getOutputStream().write(out.getBytes("UTF-8"));         } catch (UnsupportedEncodingException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    //读取方法    @Override    public void run() {        try {            BufferedReader br = new BufferedReader(                    new InputStreamReader(                            socket.getInputStream(),"UTF-8"));            String line = null;            while ((line = br.readLine()) != null) {                ChatManager.getChatManager().publish(this, line);            }            br.close();        } catch (UnsupportedEncodingException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}
ChatManager类
package com.lhy.testmyserversocket;import java.util.Vector;public class ChatManager {    /**     * 类说明:     *      客户端socket 管理类     * */    /**     * 只能有一个管理类,所以使用单例模式设计 当前类     * */    //1.让 当前类的 构造方法 变成 private    private ChatManager() {}    //2.使用 stattic fial 关键字创建当前类对象    private static final ChatManager cm = new ChatManager();    //3.创建一个公有方法,提供获取实例化对象    public static ChatManager getChatManager()    {        return cm;    }    /**     * 至此单例类创建成功     * */    /**     * Java Vector 类     *      Vector类实现了一个动态数组。和ArrayList和相似,但是两者是不同的:                Vector是同步访问的。                Vector包含了许多传统的方法,这些方法不属于集合框架。        Vector主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。     * */    Vector<ChatSocket> vector = new Vector<ChatSocket>();     //添加    public void add(ChatSocket cs) {        // vector.add(cs) 将指定元素添加到此向量的末尾,返回值是 boolean        vector.add(cs);    }    public void publish(ChatSocket cs ,String out)    {        // vector.size() 返回此向量中的组件数,返回值是int        for(int i = 0; i<vector.size();i++)        {            // vector.get(i) 返回向量中指定位置的元素。            ChatSocket csChatSocket = vector.get(i);            if(!cs.equals(csChatSocket)) //如果当前对象不是发送消息的对象            {                csChatSocket.out(out); //执行发送消息            }        }    }}    {        for(int i = 0; i<vector.size();i++)        {            ChatSocket csChatSocket = vector.get(i);            if(!cs.equals(csChatSocket)) //如果当前对象不是发送消息的对象            {                csChatSocket.out(out); //执行发送消息            }        }    }}

运行结果图

这里写图片描述

聊天服务器项目源码: [点击下载](http://download.csdn.net/detail/lihaoyang11/9714171)

在Android中创建Socket客户端 -项目源码

android项目 布局文件

<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="com.lhy.mysocketclient.MainActivity" >    <EditText        android:id="@+id/editText"        android:layout_width="500dp"        android:layout_height="270dp"        android:layout_alignLeft="@+id/editText1"        android:layout_alignRight="@+id/button1"        android:layout_below="@+id/ip"        android:ems="10"        android:inputType="textMultiLine" >        <requestFocus />    </EditText>    <Button        android:id="@+id/connect"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignBottom="@+id/ip"        android:layout_alignRight="@+id/editText"        android:text="连接" />    <Button        android:id="@+id/send"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignRight="@+id/editText"        android:text="发送" />    <EditText        android:id="@+id/ip"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignLeft="@+id/EditText01"        android:layout_alignParentTop="true"        android:ems="10"         android:text="192.168.1.89"/>    <EditText        android:id="@+id/out"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignLeft="@+id/editText"        android:layout_alignTop="@+id/send"        android:ems="10" /></RelativeLayout>

这里写图片描述

MainActivity.java 源码

package com.lhy.mysocketclient;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.net.Socket;import java.net.UnknownHostException;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class MainActivity extends Activity {    EditText ip; // 声明对象    EditText editText;    EditText text;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ip = (EditText) findViewById(R.id.ip); // 给对象赋值        editText = (EditText) findViewById(R.id.editText);        text = (EditText) findViewById(R.id.out);        // 给连接按钮添加点击事件        findViewById(R.id.connect).setOnClickListener(                new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        connect();                    }                });        // 给发送按钮添加点击事件        findViewById(R.id.send).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                send();            }        });    }    // ..........................................    Socket socket = null;    BufferedReader reader = null;    BufferedWriter writer = null;    public void connect() {        // 使用 AsyncTask 从网络读取数据        AsyncTask<Void, String, Void> read = new AsyncTask<Void, String, Void>() {            @Override            protected Void doInBackground(Void... params) {                try {                    socket = new Socket(ip.getText().toString(), 12345);                    writer = new BufferedWriter(new OutputStreamWriter(                            socket.getOutputStream()));                    reader = new BufferedReader(new InputStreamReader(                            socket.getInputStream()));                    publishProgress("@success"); // 连接成功后, 发送 @success                } catch (UnknownHostException e1) {                    Toast.makeText(MainActivity.this, "无法创建连接",                            Toast.LENGTH_SHORT).show();                } catch (IOException e1) {                    Toast.makeText(MainActivity.this, "无法创建连接",                            Toast.LENGTH_SHORT).show();                }                try {                    String line;                    // 获取接收到的数据                    while ((line = reader.readLine()) != null) {                        publishProgress(line);                    }                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                return null;            }            @Override            protected void onProgressUpdate(String... values) {                if (values[0].equals("@success")) {                    Toast.makeText(MainActivity.this, "连接成功了",                            Toast.LENGTH_SHORT).show();                }                editText.append("别人说: "+values[0]+"\n");                super.onProgressUpdate(values);            }        };        read.execute(); // 运行 AsyncTask 从网络获取数据    }    public void send() {        try {            editText.append("我说:"+text.getText().toString()+"\n");            writer.write(text.getText().toString()+"\n"); // 发送            writer.flush();            text.setText(""); // 清空 发送文本框的内容        } catch (IOException e) {            e.printStackTrace();        }    }}

给android项目开启网络权限

1. 打开 AndroidManifest.xml 文件

2. 打开 Permissions
这里写图片描述

3.点击 add
这里写图片描述

4.选择 Uses Permission
这里写图片描述

5.Name值选择 android.permission.INTERNET
这里写图片描述

6.至此我们的android项目开启使用网络权限。

0 0
原创粉丝点击