文档章节

Android Socket连接

yaly
 yaly
发布于 2015/05/06 18:19
字数 2021
阅读 470
收藏 18

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

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



实例一

客户端

Java:

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;  
    }  
  
}



XML:

<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();  
        }  
  
    }  
}



实例二

客户端

Java

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();  
        }  
  
    }  
}



XML:

<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;  
    }  
  
}



附:

一些记录:

把socket写成一个服务:


public class SocketService extends Service{  
    Thread mServiceThread;  
      
    Socket client;  
      
    @Override  
    public IBinder onBind(Intent intent) {  
        // TODO Auto-generated method stub  
        return null;  
    }  
  
    @Override  
    public void onCreate() {  
        // TODO Auto-generated method stub  
        super.onCreate();  
          
        mServiceThread = new Thread(new SocketServerThread());  
    }  
  
    @Override  
    public void onStart(Intent intent, int startId) {  
        // TODO Auto-generated method stub  
        super.onStart(intent, startId);  
          
        mServiceThread.start();  
    }  
  
    @Override  
    public void onDestroy() {  
        // TODO Auto-generated method stub  
        super.onDestroy();  
    }  
  
    public class SocketServerThread extends Thread {  
        private static final int PORT = 54321;  
          
        private SocketServerThread(){  
        }  
          
        @Override  
        public void run() {  
            try {  
                ServerSocket server = new ServerSocket(PORT);  
                  
                while(true){  
                    System.out.println("begin client connected");  
                    client = server.accept();  
                    System.out.println("client connected");  
                      
                    BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));  
                    System.out.println("read from client:");  
                      
                    String textLine = reader.readLine();  
                    if(textLine.equalsIgnoreCase("EXIT")){  
                        System.out.println("EXIT invoked, closing client");  
                        break;  
                    }  
  
                    System.out.println(textLine);  
                      
                    PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())));  
                      
                    writer.println("ECHO from server: " + textLine);  
                    writer.flush();  
                      
                    writer.close();  
                    reader.close();  
                }                             
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                System.err.println(e);  
            }     
        }  
          
    }  
}


状态:

除了isClose方法,Socket类还有一个isConnected方法来判断Socket对象是否连接成功。 看到这个名字,也许读者会产生误解。 其实isConnected方法所判断的并不是Socket对象的当前连接状态, 而是Socket对象是否曾经连接成功过,如果成功连接过,即使现在isClose返回true, isConnected仍然返回true。因此,要判断当前的Socket对象是否处于连接状态, 必须同时使用isClose和isConnected方法, 即只有当isClose返回false,isConnected返回true的时候Socket对象才处于连接状态。 虽然在大多数的时候可以直接使用Socket类或输入输出流的close方法关闭网络连接,但有时我们只希望关闭OutputStream或InputStream,而在关闭输入输出流的同时,并不关闭网络连接。这就需要用到Socket类的另外两个方法:shutdownInput和shutdownOutput,这两个方法只关闭相应的输入、输出流,而它们并没有同时关闭网络连接的功能。和isClosed、isConnected方法一样,Socket类也提供了两个方法来判断Socket对象的输入、输出流是否被关闭,这两个方法是isInputShutdown()和isOutputShutdown()。 shutdownInput和shutdownOutput并不影响Socket对象的状态。


本文转载自:http://blog.csdn.net/x605940745/article/details/17001641#t4

yaly
粉丝 3
博文 103
码字总数 48740
作品 0
海淀
Android工程师
私信 提问
android网络通信之socket教程实例汇总

一、socket基础 1、Socket通讯机制(详细),如何将socket通信的客户端与服务器 http://www.eoeandroid.com/thread-61727-1-1.html 2、Http和Socket区别 http://www.eoeandroid.com/thread-9...

程序袁_绪龙
2014/12/11
13.7K
0
android实现简单的聊天室

先说一下流程。首先是建立一个java工程,并创建两个java类,一个用于接收到客户端的连接,并把连接添加list中,第二类实现线程runnable接口,专门用来接收发送客户发送的信息。其次,建立and...

wuwulh
2012/11/09
2.2K
2
android 应用层如何连接rild

连接rild的方式,一种是通过调用framework接口来实现,通过类似PhoneFactory.getDefaultPhone()方式,当然如果要发送自定义的指令,还要增加相应的接口指令,比较麻烦,研究后再补上相关信息...

wyyew
2012/02/14
1K
2
如何从Windows应用发送通知消息给Android应用

手机应用可以作为桌面应用的辅助工具,用来接收桌面应用的状态信息。这里介绍如何实现一个简单的Android程序用于接收Windows扫描仪应用的工作状态。 参考:How to Push Notifications to An...

yushulx
2014/10/13
136
0
android的NDK和java进行本地socket通信

关于Android应用与Framework的socket通信,相信关心这个问题的朋友们已经看过《android使用socket使底层和framework通信》这篇文章,美中不足的是作者只贴出一些关键的代码片段而并没有放出源...

shouyong
2012/12/21
6.7K
0

没有更多内容

加载失败,请刷新页面

加载更多

python学习10.04:Python list列表使用技巧及注意事项

前面章节介绍了很多关于 list 列表的操作函数,细心的读者可能会发现,有很多操作函数的功能非常相似。例如,增加元素功能的函数有 append() 和 extend(),删除元素功能的有 clear()、 remo...

太空堡垒185
34分钟前
4
0
新手插画学习的方法?教你如何自学?

插画学习的方法?教你如何自学? 从小喜欢画一些漫画头像随笔画,但是其实没有基础。个人偏好小清新手绘风的插画(如下图),每每看到都希望自己能画出这样的作品。 我其实很想说画这种美术功...

huihuajiaocheng
40分钟前
5
0
面试总结

一、2019.10.15日上午交子大道中海国际艾迪泰科面试总结 1、领导比较有亲合力,就是办公环境没有隔挡,不是很喜欢办公环境 2、成都这边人员太少,感觉不到规模 3、离家太远 1、实现clone(); ...

gtandsn
51分钟前
5
0
CentOS 7 部署 tesseract-ocr

官方地址 github yum-config-manager --add-repo https://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/CentOS_7/ 若提示 yum-config-manager: command not found 执行以......

阿白
51分钟前
3
0
JAVA比较器中comparator的使用

一个专用的比较器Comparator Comparator是一个专用的比较器,当一个不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparator体现了一种策略模式...

daxiongdi
52分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部