`

socket编程学习笔记

阅读更多

       聊到socket编程,我脑子第一反应就是activeMq、及JMS的其他应用底层都是基于socket实现的,当然我们日常用的QQ、微信等通讯工具也是基于socket实现的(其实我们工作中常用到的log4j底层也用到了socket),由于socket应用面如此广泛、所以我今天翻阅了大量网上资料、并自己写了简单的例子进行学习,下面聊聊我的学习笔记和心得。

       当然在今天学习之前我就有使用过socket进行项目编码的经验了,记得当初在给某一线城市房管局做项目时,档案馆的档案都是基于PDA服务器进行存管的,PDA对外提供了socket服务,所以当初我就用的socket客户端代码去调用PDA服务发起调档的请求。

 

       下面是我11年写的代码,现在贴出来,因为当时档案馆库房很多,每个库房都有socket服务器,所以代码需要通过判断很多规则动态调用不同库房的socket服务器、并与之通讯,发送调档请求。

public boolean socketSendMessage2PDA(String daidUnionStr, int type) {
    log.info("调档发送时给PDA发送调档信息,发送的档案ID字符串为:" + daidUnionStr);
    if (daidUnionStr != null) {
        String[] daidList = daidUnionStr.split(":");
        for (String daid : daidList) {
            TpaDast tpaDast = (TpaDast) this.findEntityById("TpaDast", Long.valueOf(daid));
TpaDawzxx dawzxx = tpaDast.getDawzxx();
List<TpaDaglxxb> glxxbList = this.getDaglxxbListByDabh(tpaDast.getDacode());
            if (dawzxx != null) {
                ConfigService configService = (ConfigService) Framework.getEngine().getContainer().getComponent("configService");
String hostIP = "", cqrxm = "未知";
StringBuffer addressSbf = new StringBuffer();
                if (glxxbList != null && glxxbList.size() > 0) cqrxm = glxxbList.get(0).getCqrxm();
//根据config.properties文件中配置的档案的PDA服务地址
                //1号库房PDA服务器地址
if (dawzxx.getFh() == 1l || dawzxx.getFh().equals(1l)) hostIP = configService.getString("server1_Ip");
//2号库房PDA服务器地址
if (dawzxx.getFh() == 2l || dawzxx.getFh().equals(2l)) hostIP = configService.getString("server2_Ip");
//3号库房PDA服务器地址
if (dawzxx.getFh() == 3l || dawzxx.getFh().equals(3l)) hostIP = configService.getString("server3_Ip");
//4号库房PDA服务器地址
if (dawzxx.getFh() == 4l || dawzxx.getFh().equals(4l)) hostIP = configService.getString("server4_Ip");
//5号库房PDA服务器地址
if (dawzxx.getFh() == 5l || dawzxx.getFh().equals(5l)) hostIP = configService.getString("server5_Ip");
log.info("调用PDA服务器的IP地址为:" + hostIP);
//动态拼接PDA能够识别的位置信息
if (dawzxx.getFh() < 10) addressSbf.append("0").append(dawzxx.getFh());
                else addressSbf.append(dawzxx.getFh());
addressSbf.append(dawzxx.getQh());
                if (dawzxx.getLh() < 10) addressSbf.append("0").append(dawzxx.getLh());
                else addressSbf.append(dawzxx.getLh());
                if (dawzxx.getMh() == 1 || dawzxx.equals(1)) addressSbf.append("L");
                else if (dawzxx.getMh() == 2 || dawzxx.equals(2l)) addressSbf.append("R");
                if (dawzxx.getJh() < 10) addressSbf.append("0").append(dawzxx.getJh());
                else addressSbf.append(dawzxx.getJh());
                if (dawzxx.getGh() < 10) addressSbf.append("0").append(dawzxx.getGh());
                else addressSbf.append(dawzxx.getGh());
log.info("动态PDA库房地址为:" + addressSbf.toString());
                try {
                    //Socket发送给PDA服务器代码
Socket socket = new Socket();//需要动态根据位置发送服务
SocketAddress socketAddress = new InetSocketAddress(hostIP, 1001);
socket.connect(socketAddress, 3000);//连接三秒钟超时设置
OutputStream outputStream = socket.getOutputStream();
StringBuffer sbf = new StringBuffer();
sbf.append("<?xml version='1.0' encoding='gb2312'?>");
sbf.append("<XMLPackage>");
sbf.append("<Command CmdType='2'/>");
sbf.append("<data>");
sbf.append("<row Code='" + tpaDast.getDacode() + "' Name='" + cqrxm + "' Address='" + addressSbf.toString() + "' Archives_id='" + tpaDast.getId() + "' State='" + type + "'/>"); //还档state变成2,其它都是一样
sbf.append("</data>");
sbf.append("</XMLPackage>");
log.info("发送" + tpaDast.getDacode() + "信息为:\n" + sbf.toString());
outputStream.write(sbf.toString().getBytes());
log.info("Socket主机端连接信息为:\n" + socket);
InputStream is = socket.getInputStream();
                    byte[] bytes = new byte[1024];
                    int n = is.read(bytes);
log.info(tpaDast.getDacode() + "发送给PDA系统,回调信息为:\n" + new String(bytes, 0, n));
outputStream.flush();
outputStream.close();
is.close();
} catch (Exception e) {
                    log.info("调档发送PDA服务信息错误,调档失败,原因是PDA服务器没有开启!具体信息如下:\n" + e.getMessage());
                    return false;
}
            }
        }
    }
    return true;
}

 

 

时至今日我又翻阅了相关资料系统的进行了学习,情况总结如下:

 

概念:

Socket是一组编程接口(API), 是对TCP/IP协议的封装和应用。介于传输层和应用层,大致驻留在 OSI 模型的会话层,向应用层提供统一的编程接口。应用层不必了解TCP/IP协议细节。直接通过对Socket接口函数的调用完成数据在IP网络的传输。

 

分类:

基于传输层差异,可以将Socket分为4种类型:
    (1)基于TCP的Socket:提供给应用层可靠的流式数据服务,使用TCP的Socket应用程序协议:BGP,HTTP,FTP,TELNET等。优点:基于数据传输的可靠性。
   (2)基于UDP的Socket:适用于数据传输可靠性要求不高的场合。基于UDP的Socket应用程序或协议有:RIP,SNMP,L2TP等。
  (3)基于RawIp的Socket:非连接,不可靠的数据传输。特点:能使应用程序直接访问网络层。基于RawIp的Socket有ping ,tracert,ospf等。
  (4)基于链路层的Socket。为IS-IS协议提供的Socket接口。使IS-IS协议可通过Socket直接访问链路层。非连接,不可靠通信服务。

 

实践:

我主要是针对socket实现方式TPC/ID和UPD的两种实现方式进行了学习,先来看看他们的通讯方式链接过程图(图片来源于网络):

TCP/IP链接过程



 UPD链接过程:



 对比两者区别:

TCP:Transimission Control Protocol传输控制协议。

UPD:User Datagram Protocol用户数据包协议。

两者都属于OSI模型中的第四层——传输层的协议。

两者相比:

TCP协议面向连接,UDP协议面向非连接;(链接)

TCP协议传输速度慢,UDP协议传输速度快;(速度)

TCP有丢包重传机制,UDP没有;(重传)

TCP协议保证数据正确性,UDP协议可能丢包;(正确性)

TCP适合传递大量数据,UPD适合传递少量数据。(数据量)

 

说了基本概念后,我用代码编写了主机、客户端进行socket通讯的代码,代码如下:

服务端代码socketServer.java类:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
 * Created by 峰 on 2017/4/6.
 * 服务器类
 */
public class socketServer {
    private int port = 8189;// 默认服务器端口
public socketServer() {
    }
    // 创建指定端口的服务器
public socketServer(int port) {
        this.port = port;
}

    // 提供服务
public void service() {
        try {// 建立服务器连接
ServerSocket server = new ServerSocket(port);
// 等待客户连接
Socket socket = server.accept();
            try {
                // 读取客户端传过来信息的DataInputStream
DataInputStream in = new DataInputStream(socket
                        .getInputStream());
// 向客户端发送信息的DataOutputStream
DataOutputStream out = new DataOutputStream(socket
                        .getOutputStream());
// 获取控制台输入的Scanner
Scanner scanner = new Scanner(System.in);
                while (true) {
                    // 读取来自客户端的信息
String accpet = in.readUTF();
System.out.println(accpet);
String send = scanner.nextLine();
System.out.println("服务器:" + send);
// 把服务器端的输入发给客户端
out.writeUTF("服务器:" + send);
}
            } finally {// 建立连接失败的话不会执行socket.close();
socket.close();
}
        } catch (IOException e) {
            e.printStackTrace();
}
    }

    public static void main(String[] args) {
        new socketServer().service();
}
}

 

客户端代码socketClient.java类:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
/**
 * Created by 峰 on 2017/4/9.
 * 客户端类
 */
public class socketClient {

    private String host = "localhost";// 默认连接到本机
private int port = 8189;// 默认连接到端口8189
public socketClient() {
    }

    // 连接到指定的主机和端口
public socketClient(String host, int port) {
        this.host = host;
        this.port = port;
}

    public void chat() {
        try {
            // 连接到服务器
Socket socket = new Socket(host, port);
            try {
                // 读取服务器端传过来信息的DataInputStream
DataInputStream in = new DataInputStream(socket
                        .getInputStream());
// 向服务器端发送信息的DataOutputStream
DataOutputStream out = new DataOutputStream(socket
                        .getOutputStream());
// 装饰标准输入流,用于从控制台输入
Scanner scanner = new Scanner(System.in);
                while (true) {
                    String send = scanner.nextLine();
System.out.println("客户端:" + send);
// 把从控制台得到的信息传送给服务器
out.writeUTF("客户端:" + send);
// 读取来自服务器的信息
String accpet = in.readUTF();
System.out.println(accpet);
}

            } finally {
                socket.close();
}
        } catch (IOException e) {
            e.printStackTrace();
}
    }

    public static void main(String[] args) {
        new socketClient().chat();
}

}

 

测试结果:

服务端信息截图:

 客户端信息截图:



 

 

通讯原理及过程图解(来源于网络):



 
 

 

附言:因为时间问题、我这里只研究了java.net下的socket,其实还有别的实现方式,比如linux下面也有socket,参考 http://blog.csdn.net/hguisu/article/details/7445768/

现在网络上也有很多很好的socket学习文章,具体可以参考下面链接(当然我也都是看过了的)

http://acm.tzc.edu.cn/acmhome/projectList.do?method=projectNewsDetail&nid=2

http://blog.csdn.net/hguisu/article/details/7445768/

http://www.cnblogs.com/kinghitomi/archive/2012/01/19/2327424.html

  • 大小: 40.2 KB
  • 大小: 27.7 KB
  • 大小: 82.4 KB
  • 大小: 13.6 KB
  • 大小: 13 KB
分享到:
评论

相关推荐

    Socket网络编程学习笔记

    这份"Socket网络编程学习笔记"涵盖了从基础概念到高级技术的全面知识,对于初学者来说是一份非常有价值的参考资料。以下是对这份笔记内容的详细解读: 1. **Socket基本概念**:Socket在计算机网络中扮演着桥梁的...

    Socket网络编程学习笔记(1)

    ### Socket网络编程基础知识点 #### 一、IP地址操作类详解 在进行Socket网络编程时,熟练掌握IP地址的操作是至关重要的。以下是两个关键的类:`IPAddress`和`IPEndPoint`。 ##### 1. `IPAddress`类 `IPAddress`...

    Socket网络编程学习笔记.zip

    本学习笔记将带你深入理解这一领域,特别是通过Socket接口进行的网络通信。Socket是操作系统提供的一种通信机制,它允许应用程序创建并管理网络连接,进行数据传输。 **TCP/IP协议族** TCP/IP(Transmission ...

    Socket网络编程学习笔记(4)

    Socket网络编程是构建分布式应用程序的基础,它允许两个网络上的进程之间进行双向通信。在本文中,我们将探讨在TCP...在后续的学习笔记中,作者还将探讨如何在消息中传递实体类信息,这将进一步扩展网络通信的能力。

    VC学习笔记-基于TCP的socket编程

    ### 基于TCP的Socket编程在VC中的应用与实现 #### 一、知识点概览 在VC(Visual C++)环境下进行网络编程时,基于TCP的socket编程是实现客户端与服务器之间通信的重要方式之一。本文将从初始化、创建socket、绑定...

    Socket网络编程学习笔记(6)

    在传统的Socket编程中,每当有新的客户端请求连接时,服务端通常会创建一个新的线程来处理该连接。虽然这种方法直观易懂,但频繁地创建和销毁线程会带来较大的系统开销,包括内存分配、上下文切换等。这对于高并发的...

    socket 编程 网络编程资料大全 给力

    网络通信基础知识,socket网络编程的一些基础知识,Socket网络编程学习笔记,网络编程总结,2011-学习资料大全:java_socket编程,学习网络编程的十个步骤,socket编程入门(经典版),Unix_网络编程学习笔记,...

    Socket网络编程学习笔记(2)

    本文主要探讨面向连接的TCP Socket编程,这是一种可靠的、基于连接的通信协议。 在TCP Socket编程中,服务端需要进行一系列步骤来建立一个监听Socket,以便接受来自客户端的连接请求。以下是一个基本的服务端TCP ...

    Socket网络编程学习笔记(1)

    本文主要探讨了Socket编程中的一些常见方法,特别是IP地址操作和DNS解析相关的类。 首先,我们关注`IPAddress`类,它是处理IP地址的核心类。`IPAddress.Parse()`方法允许将点分十进制的IP地址字符串转换为`IP...

    linux嵌入式Socket网络编程学习笔记

    Socket编程允许程序通过网络发送和接收数据,是实现网络通信的基础。在Linux环境下,Socket接口被广泛用于嵌入式设备的网络功能实现,因为它提供了标准且灵活的方式来处理TCP/IP协议。 首先,我们来了解一下IP地址...

    Socket网络编程学习笔记(3)

    在本篇《Socket网络编程学习笔记(3)c# yuanma》中,我们将深入探讨如何使用C#中的套接字助手类来简化Socket编程过程,使初学者更容易掌握网络编程的基本概念。本文主要围绕服务端的侦听模式、接收客户端连接以及如何...

    socket网络编程学习笔记

    本笔记主要探讨了IP地址操作、DNS解析以及如何在服务端建立Socket监听。 首先,IP地址操作涉及到`IPAddress`和`IPEndPoint`两个类。`IPAddress`类提供了对IP地址的处理能力,如`Parse()`方法可以将点分十进制的IP...

    Socket网络编程学习笔记之---使用线程池提高性能

    本篇学习笔记将深入探讨如何结合Socket与线程池来提升程序的运行效率。 一、Socket基础 Socket,也称为套接字,是网络编程中的一个重要概念,它是进程间通信(IPC)的一种方式,特别是在网络环境中。Socket提供了一...

    学习笔记:多线程Java Socket编程示例

    在本学习笔记中,我们将探讨如何使用Java的Socket编程实现多线程服务器,特别是通过ExecutorService创建线程池来处理客户端的并发请求。ExecutorService是一个高级的线程管理工具,它允许我们更有效地管理和控制线程...

    Socket网络编程学习笔记(5)

    Socket网络编程是构建网络应用程序的基础,它允许两个设备在TCP/IP协议栈上进行通信。在本文中,我们将探讨如何在C#中使用Socket进行更复杂的通信,特别是涉及到类对象的序列化和网络传输。 首先,Socket通常用于...

Global site tag (gtag.js) - Google Analytics