使用Socket实现多人聊天应用,供大家参考,具体内容如下
在讲scoket通信器先可以先了解一下网络协议
手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。可以将网络协议分为四层,从高到低依次为:应用层、传输层、网络层、链路层。
两种Socket类型的基本通信
TCP是一个可靠的、面向连接的协议。它可以保证数据从连接的一方传递到另一方,并且发送数据的顺序和所接收数据的顺序一致。当应用程序需要一个可靠的、点对点的连接时,可以使用TCP。
UDP是一种不可靠的通信协议,没有检测错误的机制,也不重发丢失的数据。接收到的数据包的顺序可能与发送的数据包的顺序不一致。采用UDP进行通信时,事先不需要建立连接。而采用TCP进行通信时,首先要建立一个连接。TCP的通信质量比UDP高,UDP的开销比TCP小。
这里我们以TCP协议为主
其实android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信。两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户端向服务器发送请求后,服务器端才能向客户端返回数据。而Socket通信则是在双方建立起连接后就可以直接进行数据的传输,在连接时可实现信息的主动推送,而不需要每次由客户端想服务器发送请求。 那么,什么是socket?Socket又称套接字,在程序内部提供了与外界通信的端口,即端口通信。通过建立socket连接,可为通信双方的数据传输传提供通道。socket的主要特点有数据丢失率低,使用简单且易于移植。
Socket套接字概念
套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
先看一下TCP通信的步骤:
建立Socket连接
• 连接过程分为三个步骤:
?服务端监听
?客户端请求
?连接确认
(多线程机制,各个客户端和服务器之间的通信)
?服务端:ServerSocket
?客户端:Socket
?信息传输:
• 发送信息getoutputsream() write();
• 接收信息getinputstream() read();
案例:
使用TCP协议通信
java服务端,此时是使用java做服务端
ScoketDemo .java
package scoket.activity; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class ScoketDemo { public static List<Socket> clients = new ArrayList<Socket>();// 创建一个集合存放所有的客户端 /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub ServerSocket ss; while (true) { ss = new ServerSocket(2019); Socket s = ss.accept();// 使服务端处于监听状态 clients.add(s); // 为每一个客户端开设一个单个线程 new ChatThread(s).start(); // OutputStream os=client.getOutputStream(); // os.write("Nice to meet you!".getBytes("utf-8")); // os.close();//网络编程流的关闭是按栈的方式关闭的 // client.close(); } // No enclosing instance of type ScoketDemo is accessible. Must qualify // the allocation // with an enclosing instance of type // ScoketDemo (e.g. x.new A() where x is an instance of ScoketDemo). } public static class ChatThread extends Thread { Socket client; BufferedReader br; public ChatThread(Socket c) { super(); this.client = c; try { br = new BufferedReader(new InputStreamReader( client.getInputStream(), "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() { // TODO Auto-generated method stub super.run(); String content = null; // 获取客户端传递过来的数据 try { while ((content = br.readLine()) != null) { // 再将服务端的数据返回给客户端 OutputStream os = client.getOutputStream(); os.write(content.getBytes("utf-8")); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
android客户端
ChatScoketDemoActivity.java
package com.scoket.activity; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class ChatScoketDemoActivity extends Activity implements OnClickListener { /** Called when the activity is first created. */ private EditText name, setence, show; private Button btn; Socket client; Handler myHandler = new Handler() { public void handleMessage(android.os.Message msg) { if (msg.what==123) { String str = show.getText().toString(); show.setText(str +"\n"+ msg.getData().getString("chat")); } }; }; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); name = (EditText) findViewById(R.id.name); setence = (EditText) findViewById(R.id.setence); show = (EditText) findViewById(R.id.show); btn.setOnClickListener(this); new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { client = new Socket("172.20.52.26", 2019);// 网络访问最好放在线程中 new chatThread(client).start();// 启动子线程 } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } @Override public void onClick(View arg0) { // TODO Auto-generated method stub String s1 = name.getText().toString(); String s2 = setence.getText().toString(); String s3 = s1 + ":" + s2+"\n"; if (client != null) { try { client.getOutputStream().write(s3.getBytes("utf-8"));// 获取从客户端得到的数据 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //setence.setText("");//相当于刷新 } class chatThread extends Thread { Socket s; public chatThread(Socket s) { super(); this.s = s; } @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); while (true) { String content = br.readLine(); if (content != null) { Bundle bundle = new Bundle(); bundle.putString("chat", content); Message msg = new Message(); msg.setData(bundle); msg.what=123; myHandler.sendMessage(msg); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。