java学习小笔记(三.socket通信)【转】

三,socket通信
1.http://blog.csdn.net/kongxx/article/details/7288896这个人写的关于socket通信不错,循序渐进式的讲解,用代码示例说明,运用流和socket进行远程通讯

2.最简单的socket是一个服务端对应一个客户端
 server的写法

  1. ServerSocket server = new ServerSocket(10000);
  2. Socket socket = server.accept();
  3. BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  4. PrintWriter out = new PrintWriter(socket.getOutputStream());
  5. while (true) {
  6. String msg = in.readLine();
  7. System.out.println(msg);
  8. out.println("Server received " + msg);
  9. out.flush();
  10. if (msg.equals("bye")) {
  11. break;
  12. }
  13. }
  14. socket.close();

client的写法

  1. Socket socket = new Socket("localhost", 10000);
  2. BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  3. PrintWriter out = new PrintWriter(socket.getOutputStream());
  4. BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
  5. while (true) {
  6. String msg = reader.readLine();
  7. out.println(msg);
  8. out.flush();
  9. if (msg.equals("bye")) {
  10. break;
  11. }
  12. System.out.println(in.readLine());
  13. }
  14. socket.close();

3.复杂一点的就是多个客户端同时访问服务器。在客户端使用循环启动多个客户端访问同一服务端,在服务端只要server.accept()一接收到就新建线程,然后把把上面的读写操作放进线程内处理。

4.如果要利用socke传递对象,就要让对象实现Serializable 序列化接口,使用ObjectInputStream和ObjectOutputStream进行序列化和反序列化
server的写法

  1. ObjectInputStream is = null;
  2. ObjectOutputStream os = null;
  3. try {
  4. is = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
  5. os = new ObjectOutputStream(socket.getOutputStream());
  6. Object obj = is.readObject();
  7. User user = (User)obj;
  8. System.out.println("user: " + user.getName() + "/" + user.getPassword());
  9. user.setName(user.getName() + "_new");
  10. user.setPassword(user.getPassword() + "_new");
  11. os.writeObject(user);
  12. os.flush();
  13. } catch (IOException ex) {

client的写法

  1. ObjectOutputStream os = null;
  2. ObjectInputStream is = null;
  3. try {
  4. socket = new Socket("localhost", 10000);
  5. os = new ObjectOutputStream(socket.getOutputStream());
  6. User user = new User("user_" + i, "password_" + i);
  7. os.writeObject(user);
  8. os.flush();
  9. is = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
  10. Object obj = is.readObject();
  11. if (obj != null) {
  12. user = (User)obj;
  13. System.out.println("user: " + user.getName() + "/" + user.getPassword());
  14. }
  15. } catch(IOException ex) {

5.如果还需要传送时压缩流再传送,就要用到GZIPInputStream和GZIPOutputStream进行压缩和反压缩
server的写法

  1. GZIPInputStream gzipis = null;
  2. ObjectInputStream ois = null;
  3. GZIPOutputStream gzipos = null;
  4. ObjectOutputStream oos = null;
  5. try {
  6. gzipis = new GZIPInputStream(socket.getInputStream());
  7. ois = new ObjectInputStream(gzipis);
  8. gzipos = new GZIPOutputStream(socket.getOutputStream());
  9. oos = new ObjectOutputStream(gzipos);
  10. Object obj = ois.readObject();
  11. User user = (User)obj;
  12. System.out.println("user: " + user.getName() + "/" + user.getPassword());
  13. user.setName(user.getName() + "_new");
  14. user.setPassword(user.getPassword() + "_new");
  15. oos.writeObject(user);
  16. oos.flush();
  17. gzipos.finish();
  18. } catch (IOException ex) {

client的写法

  1. Socket socket = null;
  2. GZIPOutputStream gzipos = null;
  3. ObjectOutputStream oos = null;
  4. GZIPInputStream gzipis = null;
  5. ObjectInputStream ois = null;
  6. try {
  7. socket = new Socket();
  8. SocketAddress socketAddress = new InetSocketAddress("localhost", 10000);
  9. socket.connect(socketAddress, 10 * 1000);
  10. socket.setSoTimeout(10 * 1000);
  11. gzipos = new GZIPOutputStream(socket.getOutputStream());
  12. oos = new ObjectOutputStream(gzipos);
  13. User user = new User("user_" + i, "password_" + i);
  14. oos.writeObject(user);
  15. oos.flush();
  16. gzipos.finish();
  17. gzipis = new GZIPInputStream(socket.getInputStream());
  18. ois = new ObjectInputStream(gzipis);
  19. Object obj = ois.readObject();
  20. if (obj != null) {
  21. user = (User)obj;
  22. System.out.println("user: " + user.getName() + "/" + user.getPassword());
  23. }
  24. } catch(IOException ex) {

6.如果要加密传送,就要使用加密后的socket,而不是使用加密的流

server的写法,只需要对socket进行处理,流的处理不变

  1. ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
  2. ServerSocket server = factory.createServerSocket(10000);

client的写法

  1. SocketFactory factory = SSLSocketFactory.getDefault();
  2. socket = factory.createSocket("localhost", 10000);

使用加密技术,需要用到keystore文件

keytool -genkey -alias mysocket -keyalg RSA -keystore mysocket.jks

7.使用nio实现socket通信

java.nio包是Java在1.4之后增加的,用来提高I/O操作的效率。在nio包中主要包括以下几个类或接口:

* Buffer:缓冲区,用来临时存放输入或输出数据。

* Charset:用来把Unicode字符编码和其它字符编码互转。

* Channel:数据传输通道,用来把Buffer中的数据写入到数据源,或者把数据源中的数据读入到Buffer。

* Selector:用来支持异步I/O操作,也叫非阻塞I/O操作。

把对象转为字节数组

  1. public static byte[] toBytes(Object object) {
  2. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  3. ObjectOutputStream oos = null;
  4. try {
  5. oos = new ObjectOutputStream(baos);
  6. oos.writeObject(object);
  7. byte[] bytes = baos.toByteArray();
  8. return bytes;

吧字节数组转为对象

  1. ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  2. ObjectInputStream ois = null;
  3. try {
  4. ois = new ObjectInputStream(bais);
  5. Object object = ois.readObject();
  6. return object;

server端的写法

  1. Selector selector = null;
  2. ServerSocketChannel serverSocketChannel = null;
  3. try {
  4. selector = Selector.open();
  5. serverSocketChannel = ServerSocketChannel.open();
  6. serverSocketChannel.configureBlocking(false);
  7. serverSocketChannel.socket().setReuseAddress(true);
  8. serverSocketChannel.socket().bind(new InetSocketAddress(10000));
  9. serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  10. while (selector.select() > 0) {
  11. Iterator<SelectionKey> it = selector.selectedKeys().iterator();
  12. while (it.hasNext()) {
  13. SelectionKey readyKey = it.next();
  14. it.remove();
  15. execute((ServerSocketChannel) readyKey.channel());  
    1. private static void execute(ServerSocketChannel serverSocketChannel) throws IOException {
    2. SocketChannel socketChannel = null;
    3. try {
    4. socketChannel = serverSocketChannel.accept();
    5. MyRequestObject myRequestObject = receiveData(socketChannel);
    6. logger.log(Level.INFO, myRequestObject.toString());
    7. MyResponseObject myResponseObject = new MyResponseObject(
    8. "response for " + myRequestObject.getName(),
    9. "response for " + myRequestObject.getValue());
    10. sendData(socketChannel, myResponseObject);

    1. MyRequestObject myRequestObject = null;
    2. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    3. ByteBuffer buffer = ByteBuffer.allocate(1024);
    4. try {
    5. byte[] bytes;
    6. int size = 0;
    7. while ((size = socketChannel.read(buffer)) >= 0) {
    8. buffer.flip();
    9. bytes = new byte[size];
    10. buffer.get(bytes);
    11. baos.write(bytes);
    12. buffer.clear();
    13. }
    14. bytes = baos.toByteArray();
    15. Object obj = SerializableUtil.toObject(bytes);
    16. myRequestObject = (MyRequestObject)obj;

    1. sendData(SocketChannel socketChannel, MyResponseObject myResponseObject) throws IOException {
    2. byte[] bytes = SerializableUtil.toBytes(myResponseObject);
    3. ByteBuffer buffer = ByteBuffer.wrap(bytes);
    4. socketChannel.write(buffer);

client的写法

  1. socketChannel = SocketChannel.open();
  2. SocketAddress socketAddress = new InetSocketAddress("localhost", 10000);
  3. socketChannel.connect(socketAddress);
  4. MyRequestObject myRequestObject = new MyRequestObject("request_" + idx, "request_" + idx);
  5. logger.log(Level.INFO, myRequestObject.toString());
  6. sendData(socketChannel, myRequestObject);
  7. MyResponseObject myResponseObject = receiveData(socketChannel);
  8. logger.log(Level.INFO, myResponseObject.toString());
  1. private void sendData(SocketChannel socketChannel, MyRequestObject myRequestObject) throws IOException {
  2. byte[] bytes = SerializableUtil.toBytes(myRequestObject);
  3. ByteBuffer buffer = ByteBuffer.wrap(bytes);
  4. socketChannel.write(buffer);
  5. socketChannel.socket().shutdownOutput();
    1. private MyResponseObject receiveData(SocketChannel socketChannel) throws IOException {
    2. MyResponseObject myResponseObject = null;
    3. ByteArrayOutputStream baos = new ByteArrayOutputStream();
    4. try {
    5. ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
    6. byte[] bytes;
    7. int count = 0;
    8. while ((count = socketChannel.read(buffer)) >= 0) {
    9. buffer.flip();
    10. bytes = new byte[count];
    11. buffer.get(bytes);
    12. baos.write(bytes);
    13. buffer.clear();
    14. }
    15. bytes = baos.toByteArray();
    16. Object obj = SerializableUtil.toObject(bytes);
    17. myResponseObject = (MyResponseObject) obj;
    18. socketChannel.socket().shutdownInput();

    return myResponseObject;

上面的例子都需要先运行server再运行client。

时间: 2024-07-29 22:38:11

java学习小笔记(三.socket通信)【转】的相关文章

MongoDB 学习小笔记

1.配置:mongod --dbpath=D:\MongoDB\data mongo2.基本的增删查改 find() update()-- 整体更新,局部更新. 修改器: $inc db.person.update({"age":23},{$inc:{"salary":1000}}) 第一个参数为条件.第二个参数为修改的值,但值必须为整数.($inc allowed for numbers only) $set 修改器: db.person.update({&quo

网络协议栈学习(一)socket通信实例

网络协议栈学习(一)socket通信实例 该实例摘自<linux网络编程>(宋敬彬,孙海滨等著). 例子分为服务器端和客户端,客户端连接服务器后从标准输入读取输入的字符串,发送给服务器:服务器接收到字符串后,发送给服务器:服务器接收到字符串后统计字符串的长度,然后将该值传给客户端:客户端将接收到的信息打印到标准输出. 一.服务器端代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #in

Java与C之间的socket通信

最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少,而且后台服务器已经采用原始socket实现与c客户端通信,这就要求Android客户端也采用socket实现.所以在开发Android app时采用了原始socket进行编程. 由于算法是用C语言实现的,而Android应用一般是Java开发,这就不可避免得涉及Java和C语言之间的通信问题.一种

Java学习总结(三)——面向对象(上)

Java学习总结(三) -面向对象(上) 一.面向对象的概念及思考方式 面向对象的理解:是一种编程思想,他将对象作为解决问题的基本元素,利用对象与对象之间的相互作用来设计程序. 2.面向对象的思考方式:(1)首先确定问题域中的对象 (2)确定对象的特征与功能 (3)了解对象与对象之间的关系 例:设计一个五子棋游戏的对象:·黑白双方对象     ·绘制棋盘     ·输赢规则 二.类与对象 1.对象:用来描述客观事物的一个实体,由一组属性和行为构成. 2.类:(1)是一个模板,他描述一类对象的行为

Java学习整理笔记(一)Java认识

一.Java介绍: Java技术主要分成三个部分:Java语言.Java运行环境和Java类库.(一般情况下并不区分指哪个部分) 即Java并不只是一门编程语言,也是一个完整的平台,有一套庞大的开发类库(包含很多可以重复利用的代码)和提供跨平台的可移植性.自动垃圾回收以及安全性等服务的执行环境. 1.Java语言: 跟其他编程语言一样,定义的一套用于程序设计的语法规范. 2.Java运行环境: 执行Java应用程序(Java Application)必须安装 Java Runtime Envir

JAVA学习之路三 编程英文汇总学习

JAVA学习中的每个章节中都有许多英文,不断熟悉工作英语也是提高编程能力很重要的一块,对于IT行业,英语才是通用语. 记在<JAVA语言程序设计>学习的第一章英文学习之后 .class file(.class文件)                       javac command(javac命令)          .java file(.java文件)            java Development Toolkit(JDK,java开发工具包)          assembl

Java 学习札记(三)免安装版TomCat中tomcat6w.exe的运行

1.使用环境 很多时候我们用的是官网的解压免安装版的Tomcat,相比安装Tomcat除了少了安装步骤以外还少了tomcat6w.exe运行所需要的环境变量,所以一般Java开发免安装版的已经足够使用了,但是如果部署服务的时候我们不可能只运行startup.bat文件,我们需要新建一个服务并可以通过tomcat6w.exe启动和关闭服务. 2.无法运行tomcat6w.exe (1)提示错误: 运行tomcat6w.exe ,提示 指定的服务未安装 unable to open the serv

C# Socket系列三 socket通信的封包和拆包

通过系列二 我们已经实现了socket的简单通信 接下来我们测试一下,在时间应用的场景下,我们会快速且大量的传输数据的情况! 1 class Program 2 { 3 static void Main(string[] args) 4 { 5 TCPListener tcp = new TCPListener(); 6 TSocketClient client = new TSocketClient(); 7 for (int i = 0; i < 10; i++) 8 { 9 client.

Java学习整理笔记(三)数据类型

数据类型: 数据类型确定了数据在内存中占用的存储空间以及存储方式.每个数据类型都有它的取值范围,编译器根据每个变量或常量的数据类型为其分配内存空间. Java语言的数据类型可以分为两类:一类是简单数据类型(或基本数据类型),例如整数类型.浮点数类型.字符型类型和布尔类型等:另一种是引用类型,例如数组类型.类.接口等. 一.基本数据类型 8种基本数据类型,分别是字节型(byte).短整型(short).整型(int).长整型(long).字符型(char).浮点型(float).双精度型(doub