- 浏览: 15830 次
- 性别:
最新评论
-
ray_yui:
支持!!!
软件测试实习心得 -
crazy_runcheng:
不错啊= 0 =学习了 希望博主继续发有关Android的学习 ...
Android界面布局
前段时间学习了通信机制,小组做了一个仿QQ的聊天工具,能登录,注册,加好友,私聊,群聊,能玩通信游戏。我完成的任务一个你画我猜的通信游戏的模块,并完成了测试。
本文主要叙述socket的通信机制,关于你画我猜这个模块后续再写出来,这里贴的代码是我完成的模块代码中截取出来的,只为了体现逻辑思路,连贯性可能欠缺请见谅。
我们在局域网下进行socket通信,首先建立一个本机的服务器,监听端口,等待访问,当有客户端访问时,交给服务端线程处理;然后当客户端对象访问服务器时,客户端线程处理客户端的操作,通过TCP/ip协议与服务端通信。
下面先介绍一些术语:
TCP/IP协议是一种面向连接的,可靠的网络传输协议,比如你给别人打电话,必须等线路接通了、对方拿起话筒才能相互通话。而UDP协议是非面向连接的协议,就是在正式通信前不必与对方先建立连接,例如你在发短信的时候,只需要输入对方手机号就OK了。
一个TCP连接必须要经过三次“对话”才能建立起来,这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
我们要确认网络上的每一台计算机,靠的就是能唯一标识该计算机的网络地址,这个地址就叫做IP。在Internet里,IP地址是一个32位的二进制地址,为了便于记忆,将它们分为4组,每组8位,由小数点分开,用四个字节来表示,而且,用点分开的每个字节的数值范围是0~255,如202.116.0.1。
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
接下来用代码进行说明:
1、服务端:首先建立一个ServerSocket服务器端口号,当有客户端访问时,交给服务端线程处理。
服务端线程:得到连接入socket的一个输入输出流,Output写数据送到客户机,Input读取数据到服务器,自定义通信协议,根据接受数据包的不同类型进行不同处理。线程类中的run方法以及部分想客户端发送消息的方法如下,更多的向客户端发送不同类型数据的方法不再赘述:
2、客户端:创建一个客户端窗体,并初始化界面,然后启动客户端线程处理。这部分比较简单不贴代码。
客户端线程:创建对应服务端的socket套接字,连接服务器,根据通信协议,依不同的数据包类型进行处理,run方法如下
测试截图:
本文主要叙述socket的通信机制,关于你画我猜这个模块后续再写出来,这里贴的代码是我完成的模块代码中截取出来的,只为了体现逻辑思路,连贯性可能欠缺请见谅。
我们在局域网下进行socket通信,首先建立一个本机的服务器,监听端口,等待访问,当有客户端访问时,交给服务端线程处理;然后当客户端对象访问服务器时,客户端线程处理客户端的操作,通过TCP/ip协议与服务端通信。
下面先介绍一些术语:
TCP/IP协议是一种面向连接的,可靠的网络传输协议,比如你给别人打电话,必须等线路接通了、对方拿起话筒才能相互通话。而UDP协议是非面向连接的协议,就是在正式通信前不必与对方先建立连接,例如你在发短信的时候,只需要输入对方手机号就OK了。
一个TCP连接必须要经过三次“对话”才能建立起来,这三次对话的简单过程:主机A向主机B发出连接请求数据包:“我想给你发数据,可以吗?”,这是第一次对话;主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包:“可以,你什么时候发?”,这是第二次对话;主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。
我们要确认网络上的每一台计算机,靠的就是能唯一标识该计算机的网络地址,这个地址就叫做IP。在Internet里,IP地址是一个32位的二进制地址,为了便于记忆,将它们分为4组,每组8位,由小数点分开,用四个字节来表示,而且,用点分开的每个字节的数值范围是0~255,如202.116.0.1。
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
接下来用代码进行说明:
1、服务端:首先建立一个ServerSocket服务器端口号,当有客户端访问时,交给服务端线程处理。
public class Server {//服务端 public void setup(int port){ try { //绑定服务器端口号 ServerSocket sers = new ServerSocket(port); System.out.println("服务器监听端口"+port+"成功!"); while(true){ //等待客户端访问 Socket socket = sers.accept(); System.out.println("有人访问!"); //把客户端交给线程处理 SocketThread st = new SocketThread(socket); st.start(); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new Server().setup(6666); }
服务端线程:得到连接入socket的一个输入输出流,Output写数据送到客户机,Input读取数据到服务器,自定义通信协议,根据接受数据包的不同类型进行不同处理。线程类中的run方法以及部分想客户端发送消息的方法如下,更多的向客户端发送不同类型数据的方法不再赘述:
public void run() { try { // 读取客户端发送的消息 input = socket.getInputStream(); DataInputStream dis = new DataInputStream(input); // 向客户端发送的消息 output = socket.getOutputStream(); dos = new DataOutputStream(output); // 输入名字 String str = "请输入你的名字:\r\n"; // 服务器向客户端发送消息 sendMessage(str); // 读取客户端输入的名字 name = readLine(input); String name2 = name + "(" + socket.getInetAddress() + ")"; System.out.println("name:" + name2); // 从客户端读取字符串消息 while (true) { // 接受数据包的类型 int type = dis.readInt(); if (type == 1) { // 接收数据包的长度 int len = dis.readInt(); byte[] bytes = new byte[len]; dis.readFully(bytes); // 读取客户端的输入流字符串 String line = new String(bytes, "GBK"); if ("bye\n".equals(line)) { System.out.println("服务器收到 " + name + "已下线!"); break; } // 打印当前客户所说的话 System.out.println("服务器收到 " + name + ":" + line + "======"); System.out.println(keyWord+"\n======"); if (line.equals(keyWord + "\n")) {//判断对方是否猜对 System.out.println("猜对了!"); for (int i = 0; i < list.size(); i++) { SocketThread st = list.get(i); // 向其他客户端发出消息 st.sendMessage(name + "猜对了!\n"); st.sendAccess("good"); } sendTitle(); } // 群发消息 for (int i = 0; i < list.size(); i++) { SocketThread st = list.get(i); if (st == this) { continue; } // 向其他客户端发出消息 String msg = name + ":" + line; st.sendMessage(msg); } } else if (type == 2) { // 接收画图信息 int len = dis.readInt(); int x1 = dis.readInt(); int y1 = dis.readInt(); int x2 = dis.readInt(); int y2 = dis.readInt(); int r = dis.readInt(); int g = dis.readInt(); int b = dis.readInt(); Color c = new Color(r,g,b); // 群发消息 for (int i = 0; i < list.size(); i++) { // System.out.println("群发"); SocketThread st = list.get(i); // 向其他客户端发出画图消息 st.sendDraw(x1, y1, x2, y2,c); } } else if (type == 3) { if (list.size() <= 1) { return; } // 发送题目 sendTitle(); } else if (type == 4) { // 群发清屏消息 for (int i = 0; i < list.size(); i++) { SocketThread st = list.get(i); // 向所有客户端发出画图消息 st.sendClear(); } } else if (type == 5) { // 接收数据包的长度 int len = dis.readInt(); byte[] bytes = new byte[len]; dis.readFully(bytes); // 读取客户端的输入流字符串 String line = new String(bytes, "GBK"); // 给画图者发送评价消息 drawst.sendAccess(line); } } // 客户下线关闭当前端口 socket.close(); // 删除队列中的对象 list.remove(this); } catch (IOException e) { e.printStackTrace(); } }
/* * 读取输入流的方法 */ private String readLine(InputStream input) throws IOException { // 新建一个字节队列 ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataInputStream dis = new DataInputStream(input); dis.readInt(); dis.readInt(); while (true) { int n = input.read(); // System.out.println(n); // 回车符 if (n == '\r') { continue; } // 换行符 if (n == '\n') { break; } // 把读取的字节内容先保存 bos.write(n); } // 把字节队列中的数据取出来 byte[] bytes = bos.toByteArray(); String content = new String(bytes, "GBK"); return content; } /* * 向客户端发送消息的方法 */ public void sendMessage(String msg) { try { // 服务器输出流写入字节 byte[] bytes = msg.getBytes(); int len = bytes.length; dos.writeInt(1); dos.writeInt(len); dos.write(bytes); dos.flush(); } catch (IOException e) { e.printStackTrace(); } } /* * 向客户端发送画图线段消息的方法 */ public void sendDraw(int x1,int y1,int x2,int y2,Color color){ try { //客户端输出流写入字节 dos.writeInt(2); dos.writeInt(28); dos.writeInt(x1); dos.writeInt(y1); dos.writeInt(x2); dos.writeInt(y2); int red = color.getRed(); int green = color.getGreen(); int blue = color.getBlue(); dos.writeInt(red); dos.writeInt(green); dos.writeInt(blue); dos.flush(); } catch (IOException e) { e.printStackTrace(); } }
2、客户端:创建一个客户端窗体,并初始化界面,然后启动客户端线程处理。这部分比较简单不贴代码。
客户端线程:创建对应服务端的socket套接字,连接服务器,根据通信协议,依不同的数据包类型进行处理,run方法如下
public void run (){ try{ System.out.println("连接服务器......"); Socket socket = new Socket("127.0.0.1",6666); System.out.println("成功!"); //读取对方发送的消息 InputStream input = socket.getInputStream(); DataInputStream dis = new DataInputStream(input); //向对方发送的消息 output = socket.getOutputStream(); dos = new DataOutputStream(output); while(true){ //接受数据包的类型 int type=dis.readInt(); if(type==1){ //接收数据包的长度 int len = dis.readInt(); byte[] bytes= new byte[len]; dis.readFully(bytes); //读取客户端的输入流字符串 String line = new String(bytes,"GBK"); // System.out.println(line); //從服务器接收到的消息显示到界面上 l.onRecvMsg(line); }else if(type == 2){ //接收画图信息 int len = dis.readInt(); int x1 = dis.readInt(); int y1 = dis.readInt(); int x2 = dis.readInt(); int y2 = dis.readInt(); int r = dis.readInt(); int g = dis.readInt(); int b = dis.readInt(); Color c = new Color(r,g,b); l.onDraw(x1, y1, x2, y2,c); }else if(type==3){ //从服务端接受画图题目信息 int len = dis.readInt(); byte[] bytes= new byte[len]; dis.readFully(bytes); //读取客户端的输入流字符串 String str = new String(bytes,"GBK"); l.onTitle(str); }else if(type == 4){ //清屏 l.onclear(); }else if (type == 5) { // 接收数据包的长度 int len = dis.readInt(); byte[] bytes = new byte[len]; dis.readFully(bytes); // 读取客户端的输入流字符串 String line = new String(bytes, "GBK"); // 给画图者增加评价消息 l.onAccess(line); } } }catch (Exception e){ System.out.println("失败!"); e.printStackTrace(); } }其中在接受到服务端数据之后,对客户端界面处理的方法通过客户端类实现接口MsgListener来完成,这样做能使代码的设计更合理,模块之间调用更加方便。
public interface MsgListener { //在日志上显示消息 public void onRecvMsg(String str); //在画图区上画图 public void onDraw(int x1,int y1,int x2,int y2,Color color); //显示题目 public void onTitle(String str); //清屏 public void onclear(); //显示评价 public void onAccess(String access); }
测试截图:
发表评论
-
五子棋人机算法
2014-11-17 13:18 0人机算法的设计 有了棋盘棋子,实现了人人对战,即可以判 ... -
哈夫曼压缩
2014-09-26 20:47 608此文主要分析的是哈夫曼压缩的重点包括统计字符频率,建哈夫 ... -
Android界面布局
2014-08-04 16:43 1119这几天手机安卓开发的学习,让我更加感受到了JAVA的 ... -
线程------让画面动起来
2014-07-16 11:47 788线程是大部分游戏 ... -
扫雷小游戏的设计与实现
2014-05-28 23:08 766完成JAVA版扫雷的基本实现后,其实发现这并 ... -
画板感想与小结
2014-04-13 19:53 1059至画板重绘,我的 ... -
接口与抽象类
2014-04-10 19:54 855第二次学习接口和抽象类了,发现还是有很多概念不清晰和遗忘, ... -
类和对象的理解
2014-04-10 19:30 828类是具有相同属性和方法(行为)的一类事物(人),例如:书桌 ... -
参数传递
2014-04-02 22:07 4611、JAVA中的数据类型有两大类 一是基本数据类型: ...
相关推荐
Socket通信在IT行业中是网络编程的基础,特别是在C#这样的多平台开发环境中,Socket通信库的使用至关重要。本实例,"C# Socket通信稳定完整版类库实例",为我们提供了一个全面且稳定的解决方案,用于实现客户端与...
在Windows环境下进行网络编程时,Socket通信是一种常用的技术。Socket接口是操作系统提供的网络通信API,允许应用程序通过TCP/IP协议栈与其他计算机进行数据交换。本文将详细介绍Windows下的Socket通信代码,包括...
**C++ Socket通信库** C++ Socket通信库是用于实现网络通信的一种工具,它基于操作系统提供的Socket接口,为开发者提供了一种在C++程序中进行网络数据交换的标准方法。Socket库简化了网络编程,允许程序员通过调用...
Android中socket通信简单实现 socket通信需要有一个服务器和客户端,可以把同一个APP作为服务器跟客户端,也可以分开成两个APP。 先上个图: 这里以一个APP作为服务器跟客户端为示例 1、添加网络访问权限 2、写...
Socket通信的基本步骤包括:创建ServerSocket,等待客户端连接,创建Socket对象,通过输入/输出流进行数据交换,最后关闭连接。 在Mina与Socket通信的实现中,服务端通常使用Mina来创建一个Acceptor,监听特定端口...
在MATLAB环境中实现Socket通信是将强大的MATLAB计算能力与网络通信功能相结合的重要技术。Socket是一种网络编程接口,它允许程序之间通过网络进行双向通信。MATLAB提供了丰富的工具和函数来支持Socket通信,使得用户...
Socket通信是一种基于TCP/IP协议族的网络通信方式,它允许两个网络应用程序通过网络进行数据交换。在本场景中,我们关注的是C#作为服务器端,Android作为客户端的Socket通信实现。这种通信方式常用于移动应用与后台...
在IT领域,Socket通信是一种基于TCP/IP协议族的网络编程接口,用于实现不同网络设备间的双向通信。在Java中,我们可以使用Java的Socket类和ServerSocket类来构建客户端和服务器端的通信。在这个场景中,我们将讨论...
"Android+PC Socket通信"指的是通过TCP Socket协议实现Android设备(手机客户端)与个人计算机之间的数据传输。Socket通信允许应用程序之间建立端到端的连接,进行双向数据交换,非常适合用于实时通讯、文件传输等...
在Android平台上进行网络通信时,Socket通信是一种常见且重要的方式,尤其在实现聊天应用时。本文将深入探讨如何在Android中实现基于Socket的客户端和服务端通信,以构建一个简单的聊天应用。 首先,让我们理解...
本教程将详细解释如何在Android中实现Java和C的Socket通信,特别是在涉及文件描述符传递的场景下。 1. **Java Socket基础** Java中的`java.net.Socket`类提供了网络通信的能力,它允许我们在两个应用程序之间建立...
Socket通信是一种基于网络协议(如TCP/IP)进行进程间通信的技术,它允许两台计算机通过互联网交换数据。在本文中,我们将深入探讨“点到点通信”中的Socket通信代码,包括服务端和客户端的实现。 首先,让我们了解...
Socket通信在IT行业中扮演着至关重要的角色,它是网络应用程序间通信的基础。HPSocketCS是一个专为.NET平台设计的高效、稳定的Socket通信框架,适用于开发跨平台的客户端和服务器端应用。本文将深入探讨HPSocketCS的...
Java和C++之间的Socket通信是跨语言网络编程的一个常见应用场景,尤其在系统集成、设备通讯或者混合编程中。Socket提供了一种基于TCP/IP协议的进程间通信(IPC)方式,可以实现在不同操作系统上的进程之间的数据传输...
Socket 通信异常解决总结 Socket 通信异常是指在网络通信过程中出现的各种错误和异常,包括网络连接断开、服务器端或客户端程序异常、网络链路异常等。这些异常会导致 Socket 连接断开,影响系统的稳定性和可靠性。...
本篇文章将详细探讨C#中如何使用AES加密进行Socket通信,以及涉及的TCP/IP协议。 首先,让我们了解Socket通信的基础。Socket是操作系统提供的网络编程接口,它允许应用程序通过TCP/IP协议发送和接收数据。在C#中,`...
基于Qt实现局域网Socket通信系统源码。分别有服务端(Server)和客户端(Client) 服务端默认监听本机IP的6666端口 本人实测在linux(需防火墙开启端口)和windows下完美运行。基于Qt实现局域网Socket通信系统源码。...
本项目涉及的"Linux C语言 socket通信聊天小程序"是一个基础的网络聊天应用,支持群聊和私聊功能。 首先,我们需要理解什么是Socket。Socket是网络编程的一个接口,它提供了进程间通信(IPC)的能力,特别是在网络...
Socket通信是一种基于TCP/IP协议族实现的网络通信方式,它允许两台计算机通过网络进行双向通信。在文件传输中,Socket通信提供了一种灵活、高效的方法,尤其适用于大数据量或者跨平台的文件交换。以下是对Socket通信...
在Android平台上,实现基于局域网的Socket通信是一项常见的任务,尤其在开发涉及设备间通信的应用时。Socket通信允许两台设备通过网络连接直接交换数据,而无需中间服务器。在这个项目中,我们关注的是Android设备...