Iwfu-安卓网络应用---Socket

2023-10-15 12:38

本文主要是介绍Iwfu-安卓网络应用---Socket,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Socket

 socket套接字,和java网络编程部分类似,通过socket可以实现客户端与服务器的链接(c/s),使用ServerSocket可以创建TCP服务器端,与客户端建立三次握手连接。

通过一个例子熟悉:

简单的c/s聊天室

服务器端

(使用MyEclipse编写的):
public static void main(String args[]){

    try {ServerSocket serverSocket = new ServerSocket(SERVER_PORT);System.out.println("启动了服务器");while(true){Socket socket = serverSocket.accept();socketList.add(socket);System.out.println("成功连接客户端");//为每一个客户端socket单独开启一个线程通信new Thread(new MyServerThread(socket)).start();}} catch (IOException e) {e.printStackTrace();} }

主要通过 new ServerSocket(port)启动服务器Socket,再调用accepet(),接收来自客户端的链接请求,因为是聊天室,一个客户端发送信息要同时让其他客户端收到,所以给每个客户端socket开启一个线程用于发送和读取消息。

客户端自定义线程类,用于处理服务器和客户端的交互数据:

@Overridepublic void run() {String content = null;//采用循环不断的从Socket中读取客户端发送过来的数据while ((content = readFromClient()) != null) {for (Socket socket : MyServer.socketList) {//遍历每个Socket,把读到的内容向每一个Socket发送一遍try {OutputStream outputStream =    socket.getOutputStream();outputStream.write((content+"\n").getBytes("utf-8"));} catch (IOException e) {e.printStackTrace();}}}}

读数据的方法:

    /** 从客户端读取数据到服务器*/private String readFromClient() {String content = null;try {content = bufferedReader.readLine();return content;} catch (IOException e) {e.printStackTrace();// 捕捉到异常,说明该Socket对应的客户端已关闭MyServer.socketList.remove(socket);}return null;}

然后运行,服务器端就准备好了 : )

客户端(用AndroidStudio编写):

客户端界面:简单聊天界面,一个EditText,一个Button发送信息,一个TextView显示从服务器读取的信息.重点在于如何与服务器进行连接和从子线程修改UI线程(主线程)组件。

关键代码(MainActivity):

public static String URL_PATH = "192.168.2.1";  //访问服务器地址public static int SERVER_PORT = 50000;  //服务器端口号public static int TIMEOUT = 5000; //超时限定public static final int MESSAGE_APPENDTEXT = 0x111;public static final int MESSAGE_EDITTEXT = 0x111;
private Handler myHandler = new Handler () {@Overridepublic void handleMessage (Message msg) {super.handleMessage (msg);if (msg.what == MESSAGE_APPENDTEXT) {textView.append (msg.obj.toString () + "\n");} else if (msg.what == 0x222) {Toast.makeText (MainActivity.this, "连接服务器失败", Toast.LENGTH_SHORT).show ();}}};
private void initViews () {textView = (TextView) findViewById (R.id.textView);button = (Button) findViewById (R.id.button);editText = (EditText) findViewById (R.id.editText);button.setOnClickListener (new View.OnClickListener () {@Overridepublic void onClick (View v) {Message message = new Message ();message.what = MainActivity.MESSAGE_EDITTEXT;message.obj = editText.getText ().toString ();myClientThread.revHandler.sendMessage (message);editText.setText ("");}});}
@Overrideprotected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState);setContentView (R.layout.activity_main);initViews ();myClientThread = new MyClientThread (myHandler);new Thread (myClientThread).start ();}

客户端子线程的实现类MyClientThread :

public class MyClientThread implements  Runnable{private Handler handler; //向ui发送消息的Handler对象public Handler revHandler; //接受ui发来的消息的Handler对象private BufferedReader bufferedReader;private OutputStream outputStream;public MyClientThread(Handler handler){this.handler = handler;}@Overridepublic void run () {try {//建立Socket连接服务器Socket socket = new Socket (MainActivity.URL_PATH,MainActivity.SERVER_PORT);socket.setSoTimeout (MainActivity.TIMEOUT);bufferedReader = new BufferedReader (new InputStreamReader (socket.getInputStream ()));outputStream = socket.getOutputStream ();//启动一条子线程来读取服务器的数据new Thread (new Runnable () {String content;@Overridepublic void run () {try {while((content = bufferedReader.readLine ())!=null){Message message = new Message ();message.what = MainActivity.MESSAGE_APPENDTEXT;message.obj = content;handler.sendMessage(message);}} catch (IOException e) {e.printStackTrace ();}}}).start ();Looper.prepare ();revHandler = new Handler (){@Overridepublic void handleMessage (Message msg) {//接受用户输入的数据if (msg.what==MainActivity.MESSAGE_EDITTEXT){try {outputStream.write ((msg.obj.toString ()+"\r\n").getBytes ("utf-8"));} catch (IOException e) {e.printStackTrace ();}}}};Looper.loop ();}catch (SocketTimeoutException e){Log.e ("TimeOut", "连接服务器超时");} catch (SocketException e) {e.printStackTrace ();} catch (UnknownHostException e) {e.printStackTrace ();} catch (IOException e) {e.printStackTrace ();}}
}

为什么要在子线程中还开一条子线程用于读取服务器数据呢?我想是因为怕子线程发送数据给服务器的同时,其他客户端向服务器也发送了数据,对于我自己这个客户端就要从服务器接收数据(就是聊天室别人发信息我同时也要从服务器接收到信息),收发同时为了避免线程拥塞,所以在子线程中再开一个子线程单独用于发送数据给服务器。

注意的地方:

网络通信在安卓中一般放在子线程中进行,主线程一般用于UI操作。
安卓网络通信加权限:
<uses-permission android:name="android.permission.INTERNET"/>

截图:

启动服务器:
启动服务器

客户端:

客户端

完结撒花,如有不足,望批评指正。

附:源码下载-

Rose.Chan—Socket简易聊天室

这篇关于Iwfu-安卓网络应用---Socket的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/217746

相关文章

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“

安卓玩机工具------小米工具箱扩展工具 小米机型功能拓展

小米工具箱扩展版                     小米工具箱扩展版 iO_Box_Mi_Ext是由@晨钟酱开发的一款适用于小米(MIUI)、多亲(2、2Pro)、多看(多看电纸书)的多功能工具箱。该工具所有功能均可以免root实现,使用前,请打开开发者选项中的“USB调试”  功能特点 【小米工具箱】 1:冻结MIUI全家桶,隐藏状态栏图标,修改下拉通知栏图块数量;冻结

安卓开发板_联发科MTK开发评估套件串口调试

串口调试 如果正在进行lk(little kernel ) 或内核开发,USB 串口适配器( USB 转串口 TTL 适配器的简称)对于检查系统启动日志非常有用,特别是在没有图形桌面显示的情况下。 1.选购适配器 常用的许多 USB 转串口的适配器,按芯片来分,有以下几种: CH340PL2303CP2104FT232 一般来说,采用 CH340 芯片的适配器,性能比较稳定,价

Java Socket服务器端与客户端的编程步骤总结

一,InetAddress类: InetAddress类没有构造方法,所以不能直接new出一个对象; 可以通过InetAddress类的静态方法获得InetAddress的对象; InetAddress.getLocalHost(); InetAddress.getByName(""); 类主要方法: String - address.getHostName(); String - addre

VC环境下window网络程序:UDP Socket程序

最近在学Windows网络编程,正好在做UDPsocket的程序,贴上来: 服务器框架函数:              socket();    bind();    recfrom();  sendto();  closesocket(); 客户机框架函数:            socket();      recfrom();  sendto();  closesocket();

安卓实现弹出软键盘屏幕自适应调整

今天,我通过尝试诸多方法,最终实现了软键盘弹出屏幕的自适应。      其实,一开始我想通过EditText的事件来实现,后来发现,安卓自带的函数十分强大,只需几行代码,便可实现。实现如下:     在Manifest中设置activity的属性:android:windowSoftInputMode="adjustUnspecified|stateHidden|adjustResi

socket()接口与内核协议栈的挂接

最近在看Brdige的代码,发现一个问题,同样的调用ioctl接口实现添加网桥、删除网桥、网桥增加网卡、网桥删除网卡等操作,一个应用层的接口,却通过两条路径实现,sock_ioctl和RTNETLINK(这本就不是一个级别的东西),而应用层的brctl-utils源码中并没有直接使用PF_NETLINK协议簇的情况,让我感到非常奇怪,因此想把glibc到系统调用,到协议簇注册,以及和VFS的关系再

linux下的Socket网络编程教程

套接字概念 Socket本身有“插座”的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。与管道类似的,Linux系统将其封装成文件的目的是为了统一接口,使得读写套接字和读写文件的操作一致。区别是管道主要应用于本地进程间通信,而套接字多应用于网络进程间数据的传递。在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程。

socket函数接收发送详解

http://blog.csdn.net/g_brightboy/article/details/12854117 http://blog.csdn.net/liangkaiyang/article/details/5931901 send。。。 这里只描述同步Socket的send函数的执行流程。 当调用该函数时,send先比较待发送数据的长度