创建服务器端的步骤
1,指定端口实例化一个ServerSocket

2,调用ServerSocket的accept方法等待连接期间阻塞

3,获取位于底层的Socket流进行读写操作

4,将数据封装成流

5,对Socket进行读写

6,关闭流

创建客户端的步骤:

1,通过IP地址和端口实例化Socket,请求连接服务器

2,获取位于底层的Socket流进行读写操作

3,将数据封装成流(BufferedReader/PrintWriter,DataOutputStream/DataInputStream)的实例

4,对Socket进行读写

5,关闭流

使用ServerSocket创建服务器端:

public static void main(String[] args) throws IOException {// TODO Auto-generated method stub//创建一个ServerSo查看特,用于监听客户端Socket的连接请求ServerSocket ss=new  ServerSocket(3000);while(true){//每当接收到客户端Socket的请求,服务器端也对应产生一个Socket,没接收到请求就等待。。Socket s=ss.accept();OutputStream os=s.getOutputStream();//服务器端产生的Socket获取输出流os.write("您好,您收到了来自服务器的祝福!\n".getBytes());os.close();s.close();}}

客户端使用Socket通信:
测试环境是PC端服务器,手机当客户端,PC和手机要连接同一个局域网,PC和手机在同一网段

package com.example.simpleclient;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;public class MainActivity extends Activity {TextView text;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text=(TextView) findViewById(R.id.text);new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubtry {//建立连接到远程服务器的的Socket,Ip是服务器端PC的IP,测试环境是PC端服务器,手机当客户端,PC和手机要连接同一个局域网,PC和手机在同一网段Socket socket = new Socket("192.168.88",3000);//将Socket对应的输入流包装秤BufferedReaderBufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));String line=br.readLine();text.setText("来自服务的数据:"+line);br.close();socket.close();} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}                                   }}.start();}}
 <!-- 访问网络权限 --><uses-permission android:name="android.permission.INTERNET"/>

客户端和服务器端的输入输出流的问题容易搞混淆:如下图

在客户端:

socket.getInputStream();从socket读来自服务器的数据

socket.getOutputStream();向socket中写数据,传给服务器,服务器在它的socket的输入流读这个数据

在服务器端:

socket.getInputStream();从socket读来自客户端的数据

socket.getOutputStream();向socket中写数据,传给客户端,客户端在它的socket的输入流读这个数据

就是说客户端和服务器端的输入输出流是对应的,输入流连接到输出流

输入输出流的包装:

第一种方法:数据二进制流

DataInputStream in=new DataInputStream(socket.getInputStream());//接收客户端信息
DataOutputStream out=new DataOutputStream(socket.getOutputStream());  //向客户端发送消息

第二种方法:

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

socketClient,java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;public class socketClient extends Activity {private Button button;private TextView text;private EditText edit;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);button = (Button) findViewById(R.id.button);edit = (EditText) findViewById(R.id.edit);text = (TextView) findViewById(R.id.text);button.setOnClickListener(new View.OnClickListener() {private Socket socket = null;@Overridepublic void onClick(View v) {// TODO Auto-generated method stubString sendMsg = edit.getText().toString() + "\r\n";try {socket = new Socket("192.168.0.37", 8888); // 创建Socket,其中ip地址为我的PC机器的地址,手机通过wifi上网和服务器在一个网段// PrintWriter out = new PrintWriter(new BufferedWriter(new// OutputStreamWriter(socket.getOutputStream())),true);// out.println(sendMsg);//                    // BufferedReader in = new BufferedReader(new// InputStreamReader(socket.getInputStream()));// String readMsg = in.readLine();// if(readMsg !=null){// text.setText(readMsg);// }else{// text.setText("错误");// }//                 // out.close();// in.close();// socket.close();DataOutputStream out = new DataOutputStream(socket.getOutputStream()); // 向服务器发送消息out.writeUTF(sendMsg);out.flush();DataInputStream in = new DataInputStream(socket.getInputStream()); // 接收来自服务器的消息String readMsg = in.readUTF();if (readMsg != null) {text.setText(readMsg);}out.close();in.close();socket.close();} catch (Exception e) {e.printStackTrace();}}});}
}

Server.java

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;public class Server {public Server(){new ServerThread().start();}class ServerThread extends Thread{public void run() {try {ServerSocket ss=new ServerSocket(8888); 创建一个ServerSocket对象,并让这个ServerSocket在8888端口监听while(true){Socket socket=ss.accept(); //调用ServerSocket的accept()方法,接受客户端所发送的请求,如果客户端没有发送数据,那么该线程就停滞不继续
//                  try {
//                      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  //接收客户端信息
//                      String readline = in.readLine();
//                      System.out.println("readline:"+readline);
//
//                      PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
//                      out.println("link server success");
//
//                      in.close();   //关闭流
//                      out.close();//关闭流
//                      socket.close();//关闭打开的socket
//
//                  } catch (Exception e) {
//                      // TODO: handle exception
//                  }finally{
//                  //  socket.close();//
//                  }try {DataInputStream in=new DataInputStream(socket.getInputStream());//接收客户端信息String readline=in.readUTF();System.out.println(readline);DataOutputStream out=new DataOutputStream(socket.getOutputStream());  //向客户端发送消息out.writeUTF("link server success");out.flush();in.close();   //关闭流out.close();//关闭流socket.close();//关闭打开的socket} catch (Exception e) {System.out.println(e.getMessage());}}} catch (IOException e) {System.out.println(e.getMessage());}}}public static void main(String[] args) throws IOException {new Server();   //开启服务器}}

加入多线程:聊天室

客户端和服务器端保持长时间的通信,服务器需要不断的读取客户端数据,并向客户端写入数据,客户端也需要不断的读取服务器的数据

服务器应该为每个Socket单独启动一条线程,每条线程负责与一个客户端进行通信

服务器端:

package com.hust.multithred;import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;public class MyServer {/*** @param args* @throws IOException *///服务器端保存所有Socket的ArrayListpublic static  ArrayList<Socket> socketlist=new ArrayList<Socket>();public static void main(String[] args) throws IOException {// TODO Auto-generated method stubServerSocket ss=new ServerSocket(3000);//ServerSocket监听3000端口while(true){Socket socket_in_server=ss.accept();//循环等待客户端的Socketsocketlist.add(socket_in_server);   //每接收到一个客户端的Socket,将服务器端产生的与之对应的Socket加入数组//为每一个Socket单独启动一条线程,每个线程负责与一个客户端进行通信SocketThread socketthread=new SocketThread(socket_in_server);new Thread(socketthread).start();}}}
package com.hust.multithred;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;public class SocketThread implements Runnable{//线程任务类,实现Runnable接口Socket s=null;BufferedReader br=null;public SocketThread(Socket s) throws IOException{this.s=s;br=new BufferedReader(new InputStreamReader(s.getInputStream()));//Socket输入流包装成字符流,来自客户端的数据在此输入流上,服务器端可以读}public void run() {// TODO Auto-generated method stubtry {String content=null;//循环不断冲Socket中读取客户端发送过来的数据while((content=readFormClient())!=null){//每读到数据之后,将读到的内容向每个Socket发送一次for(Socket s:MyServer.socketlist){                    OutputStream os=s.getOutputStream();os.write((content+"\n").getBytes("utf-8"));   //写到每个socket 的输出流上              }}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//从输入流上读取来自客户端的数据方法public String readFormClient(){String content=null;try {content = br.readLine();} catch (IOException e) {// TODO Auto-generated catch blockMyServer.socketlist.remove(s);}return content;}}

客户端:

MainActivity.java

package com.hust.multithreadclient;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
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;@Overrideprotected 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接收来自子线程的消息,负责处理消息,更新UIhandler=new Handler(){@Override//如果消息来自子线程public void handleMessage(Message msg) {// TODO Auto-generated method stubif(msg.what==0x123){show.append("\n"+msg.obj.toString());}}};//客户端启动ClientThread线程创建玩过连接,读取来自服务器的数据new Thread(new ClientThread(handler)).start();send.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// 当用户按下发送按钮后,将用户输入的数据封装成Message,发给子线程的Handler,此处handler负责发送消息Message msg=new Message();msg.what=0x111;msg.obj=input.getText().toString();clientthread.rvhandler.sendMessage(msg);//发给子线程的Handlerinput.setText("");}          });}@Overridepublic 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;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}
}

ClientThread.java

package com.hust.multithreadclient;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;import android.os.Handler;
import android.os.Looper;
import android.os.Message;public class ClientThread implements Runnable {Socket s;Handler handler;  //定义向UI线程发送消息的Handler对象Handler rvhandler; //定义接收UI线程消息的Handler对象BufferedReader br=null;OutputStream os=null;public ClientThread(Handler handler){this.handler=handler;}@Overridepublic void run() {// TODO Auto-generated method stubtry {s=new Socket("192.168.1.88",3000);br=new BufferedReader(new InputStreamReader(s.getInputStream()));os=s.getOutputStream();//启动一条子线程来读取服务器端相应的数据new Thread(){@Overridepublic void run() {// TODO Auto-generated method stubString content=null;try{while((content=br.readLine())!=null){Message msg=new Message();msg.what=0x123;msg.obj=content;handler.sendMessage(msg);//此子线程中仅仅是读来自服务器的数据,并发给UI线程的Handler处理}}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}.start();/** 当前客户端线程中Handler,Android线程之间的通信是Handler来实现* 此Hnadler接收UI线程发过来的数据,即用户的输入,并写到输出流* 因为此Handler是接收处理消息,所以需要使用Looper* */Looper.prepare();rvhandler=new Handler(){@Overridepublic void handleMessage(Message msg) {//如果接收到UI线程中用户输入的数据if(msg.what==0x111){try{//将用户在文本框内的输入内容写入网络os.write((msg.obj.toString()+"\r\n").getBytes("utf-8"));}catch(IOException e){e.printStackTrace();                          }}}};Looper.loop();//启动looper} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

Android网络编程的Socket通信总结相关推荐

  1. Linux C++服务器项目——网络编程1 (socket通信,服务端,客户端)

    牛客 C++高并发服务器开发 参考笔记 1.MAC地址 2 IP地址 2.1 简介 2.2 IP地址编址方式 2.3 子网掩码 3 端口 3.1 简介 3.2 端口类型 4 网络模型 4.1 OSI七 ...

  2. socket网络编程——基于socket通信实现对客户端与服务器间的文件互传

    客户端与服务器间的文件互传 基于socket的文件数据互传,将文件中所有的字符一一通过buf进行传递,为了更好地判断文件的 结束,通过添加文件结束标识符"#",当接收端接收到该字符 ...

  3. Android网络编程系列 一 Socket抽象层

    在<Android网络编程>系列文章中,前面已经将Java的通信底层大致的描述了,在我们了解了TCP/IP通信族架构及其原理,接下来我们就开始来了解基于tcp/ip协议层的Socket抽象 ...

  4. 【Android 应用开发】Android 网络编程 API笔记 - java.net 包 权限 地址 套接字 相关类 简介

    Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...

  5. 【Android】Android网络编程概述

    Android网络编程概述 原文来自:http://blog.csdn.net/kieven2008/article/details/8210737 首先,应该了解的几个问题: 1)Android平台 ...

  6. Android网络编程(八) 之 HttpURLConnection原理分析

    1 使用回顾 我们在前面博文<Android网络编程(四) 之 HttpClient与HttpURLConnection>中已经对HttpURLConnection的使用进行过介绍.今天我 ...

  7. Android网络编程(一)

    Android网络编程概述 首先,应该了解的几个问题: 1)Android平台网络相关API接口 a) java.net.*(标准Java接口) java.net.*提供与联网有关的类,包括流.数据包 ...

  8. Android网络编程基础(一) - 基础知识

    内容介绍:Android网络编程基础 博客地址:http://blog.csdn.net/kevindgk 版权声明:本文为原创文章,未经允许不得转载 联系方式:815852777@qq.com 前言 ...

  9. 基于Http协议的Android网络编程

    之前写过一篇Android网络编程<浅谈android网络编程>,随着了解了更多Android知识,我意识到HttpClient已经不推荐使用了,更是在Android 6.0中被废弃了,原 ...

最新文章

  1. Bzoj3530: [Sdoi2014]数数
  2. error LNK2001: 无法解析的外部符号 public: static int Pe...
  3. 微信公众号开发之准备工作
  4. Servlet3.0 || IDEA与tomcat的相关配置
  5. ORB-SLAM / ORB-SLAM2原理解读+代码解析(汇总了资料,方便大家学习)
  6. catch句子_「实用英文」知道 catch on 是什么意思吗?catch 精选短语合集
  7. tomcat下只有.class文件 没有java文件_解决tomcat发布工程后,WEB-INF/classes下文件不编译的问题...
  8. 13_展示商品的详情
  9. Carrot2对文章进行聚类代码示例
  10. 大数据趋势下,服务风暴必将来临
  11. 最棒的60个DevOps开源工具
  12. 第十三天 06-文本编辑器VI的使用修改网卡等
  13. 欧姆龙服务器显示oE,在公网如何配置OE客户端
  14. php 聊天室 教程,基于PHP的聊天室编程思想-PHP教程,PHP基础
  15. 消费者信任缺失,拼多多解决不了的问题其他平台能解决吗?
  16. CF Educational Round 57(1096) 比赛记录
  17. 撤销院士称号!两名原院士,被当作反面典型通报
  18. Oracle报错ORA-19400 ORA-24279产生原因和MOS官方解决办法
  19. 用mysql搭建蚂蚁笔记_搭建蚂蚁笔记(服务器)
  20. three.js流动线

热门文章

  1. C++ Primer 5th笔记(chap 17 标准库特殊设施)bitset类型
  2. 区块链BaaS云服务(16)天德链TDBC“泰山沙盒系统”
  3. C++ Primer 5th笔记(chap 14 重载运算和类型转换)二义性类型转换
  4. 从(0,0)到(n,n)——广度优先及其改进
  5. windows平台下安装Mysql8.0.20版本
  6. CVE-2014-4113_Win32k提权漏洞学习笔记
  7. 快来捡武器:Black Hat USA 将推出的8款安全工具
  8. Kibana远程代码执行漏洞攻击方法和漏洞原理分析
  9. 用户层和内核层异常的处理流程
  10. MySQL创建存储过程(CREATE PROCEDURE)