`

Java Socket技术总结

 
阅读更多
1       Socket通信原理1.1     ISO七层模型
1.2     TCP/IP五层模型
         应用层相当于OSI中的会话层,表示层,应用层。

1.3     TCP报文
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
  (2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
  (3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
  (A)URG:紧急指针(urgent pointer)有效。
  (B)ACK:确认序号有效。
  (C)PSH:接收方应该尽快将这个报文交给应用层。
  (D)RST:重置连接。
  (E)SYN:发起一个新连接。
  (F)FIN:释放一个连接。

需要注意的是:
  (A)不要将确认序号Ack与标志位中的ACK搞混了。
  (B)确认方Ack=发起方Req+1,两端配对。
1.4     Socket通信
       Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
1.5     三次握手
         Socket连接建立和关闭,详见:http://www.2cto.com/net/201310/251896.html
2       通信基本概念2.1     短连接
连接->传输数据->关闭连接
短连接是指SOCKET连接,发送数据,接收数据后,马上断开连接。
比如:
HTTP1.0默认是短连接,无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。 、
Http1.1默认是长连接
无状态:协议对于事务处理没有记忆能力;
2.2     长连接
连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。
建立SOCKET连接后,不管是否使用,一致保持连接。
2.3     半包
接受方没有接受到一个完整的包,只接受了部分;
原因:TCP为提高传输效率,将一个包分配的足够大,导致接受方并不能一次接受完。
影响:长连接和短连接中都会出现
2.4     粘包
发送方发送的多个包数据到接收方接收时粘成一个包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
分类:一种是粘在一起的包都是完整的数据包,另一种情况是粘在一起的包有不完整的包
出现粘包现象的原因是多方面的:
1)发送方粘包:由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一包数据。若连续几次发送的数据都很少,通常TCP会根据优化算法把这些数据合成一包后一次发送出去,这样接收方就收到了粘包数据。
2)接收方粘包:接收方用户进程不及时接收数据,从而导致粘包现象。这是因为接收方先把收到的数据放在系统接收缓冲区,用户进程从该缓冲区取数据,若下一包数据到达时前一包数据尚未被用户进程取走,则下一包数据放到系统接收缓冲区时就接到前一包数据之后,而用户进程根据预先设定的缓冲区大小从系统接收缓冲区取数据,这样就一次取到了多包数据。
2.5     分包
分包(1):在出现粘包的时候,我们的接收方要进行分包处理;
分包(2):一个数据包被分成了多次接收;
原因:1. IP分片传输导致的;2.传输过程中丢失部分包导致出现的半包;3.一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系)。
影响:粘包和分包在长连接中都会出现
2.6     如何解决半包,粘包问题
出现粘包和半包现象,是因为TCP当中,只有流的概念,没有包的概念。
UDP不会出现半包,粘包情况,原因是UDP是一个完整的数据包,发送时不进行合并,因此接收的时候就不存在粘包情况。

固定长度:每次发送固定长度的数据;
特殊标示:以回车,换行作为特殊标示;获取到指定的标识时,说明包获取完整。
字节长度:包头+包长+包体的协议形式,当服务器端获取到指定的包长时才说明获取完整;

2.7     什么时候需要考虑粘包的情况
短连接:不用考虑粘包的情况;
发送数据无结构,如文件传输,这样发送方只管发送,接收方只管接收存储,也不用考虑粘包;
长连接:需要在连接后一段时间内发送不同结构数据;

处理方式:接收方创建一预处理线程,对接收到的数据包进行预处理,将粘连的包分开;
2.8     TCP与UDP的差别
  • 基于连接与无连接;
  • 对系统资源的要求(TCP较多,UDP少);
  • UDP程序结构较简单;
  • 流模式与数据报模式 ;
  • TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
  • 网络分化:机器本身是好的,但是之间的通信出现问题;
  • 网络抖动:网络中的延迟是指信息从发送到接收经过的延迟时间,一般由传输延迟及处理延迟组成;而抖动是指最大延迟与最小延迟的时间差,如最大延迟是20毫秒,最小延迟为5毫秒,那么网络抖动就是15毫秒,它主要标识一个网络的稳定性。
2.9     其他通信问题2.10         参考资料
一个包没有固定长度,以太网限制在46-1500字节,1500就是以太网的MTU,超过这个量,TCP会为IP数据报设置偏移量进行分片传输,现在一般可允许应用层设置8k(NTFS系)的缓冲区,8k的数据由底层分片,而应用看来只是一次发送。

对于UDP,就不要太大,一般在1024至10K。注意一点,你无论发多大的包,IP层和链路层都会把你的包进行分片发送,一般局域网就是1500左右,广域网就只有几十字节。分片后的包将经过不同的路由到达接收方,对于UDP而言,要是其中一个分片丢失,那么接收方的IP层将把整个发送包丢弃,这就形成丢包。

TCP作为流,发包是不会整包到达的,而是源源不断的到,那接收方就必须组包。而UDP作为消息或数据报,它一定是整包到达接收方。

关于接收,一般的发包都有包边界,首要的就是你这个包的长度要让接收方知道,于是就有个包头信息,对于TCP,接收方先收这个包头信息,然后再收包数据。一次收齐整个包也可以,可要对结果是否收齐进行验证。这也就完成了组包过程。UDP,那你只能整包接收了。要是你提供的接收Buffer过小,TCP将返回实际接收的长度,余下的还可以收,而UDP不同的是,余下的数据被丢弃并返回WSAEMSGSIZE错误。注意TCP,要是你提供的Buffer佷大,那么可能收到的就是多个发包,你必须分离它们,还有就是当Buffer太小,而一次收不完Socket内部的数据,那么Socket接收事件(OnReceive),可能不会再触发,使用事件方式进行接收时。
3       Socket实例3.1     Socket通信模型


3.2     Socket架构完整模型
  • 解决半包,粘包(编解码)
  • 服务端支持多线程
  • 支持心跳检测
  • 指定端口实例化一个SeverSocket
  • 调用ServerSocket的accept()方法,以在等待连接期间造成阻塞
  • 获取位于该底层的Socket的流以进行读写操作
  • 将数据封装成流
  • 对Socket进行读写
  • 关闭打开的流
3.3     服务端开发
//建立ServerSocket对象,监听绑定端口
ServerSocket server=new ServerSocket(1000);

//建立接收Socket,阻塞响应
Socket client=server.accept();

//获得输入流,用于接收客户端信息
InputStream in=server.getInputStream();
//获得输出流,用于输出客户端信息

//对输入流进行包装,方便使用
BufferedReader inRead=new BufferedReader(new InputStreamReader(in));
//对输出流进行包装,方便使用
PrintWriter outWriter=new PrintWriter(out);

while(true)
{
String str=inRead.readLine();//读入
outWriter.println("输出到客户端");
outWriter.flush();//输出
if(str.equals("end"))
{
break;
}
}
//关闭Socket
client.close();
server.close();

3.4     客户端开发
  • 通过IP地址和端口实例化Socket,请求连接服务器
  • 获得Socket上的流以进行读写
  • 把流封装进BufferedReader/PrintWriter的实例
  • 对Socket进行读写
  • 关闭打开的流

//使用Socket,建立与服务端的连接
Socket client=new Socket("127.0.0.1",1000);
InputStream in=client.getInputStream();//获得输入流
OutputStream out=client.getOutputStream();//获得输出流
//包装输入流,输出流
BufferedReader inRead=new BufferedReader(new InputStreamReader(in));
PrintWriter outWriter=new PrintWriter(out);
//获得控制台输入
BufferedReader inConsole=new BufferedReader(new InputStreamReader(in));
while(true)
{
String str=inConsole.readLine();//读取控制台输入
outWriter.println(str);//输出到服务端
outWriter.flush();//刷新缓冲区
if(str.equals("end"))
{
break;
}//退出
System.out.println(inRead.readLine())//读取服务端输出
}
client.close();

DOS下运行客户端
java -classpath sockettest-0.0.1-SNAPSHOT.jar cn.com.gome.sockettest.basic.ClientTest
3.5     多线程服务端
3.6     心跳检测
         方法1:socket.sendUrgentData(0);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
try{
      socket.sendUrgentData(0xFF);
}catch(Exception ex){
      reconnect();
}
         只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的。

         方法2:自定义心跳字符串
3.7     各类数据读写
         传输字节,字符,对象【ObjectInputStream ObjectOutputStream】(实例)
分享到:
评论

相关推荐

    总结java_socket编程.doc

    Java Socket 编程总结 Java Socket 编程是Java语言中用于网络编程的主要技术之一。它允许开发者创建网络应用程序,通过Socket实现客户机/服务器结构的通信。在Java中,Socket编程主要是基于TCP/IP协议的网络编程。 ...

    java Socket 多线程

    总结来说,Java Socket多线程是构建高并发网络服务的关键技术。通过合理地设计和实现,可以有效地提升服务器的并发处理能力,为用户提供更高效的服务。在实际项目中,应根据具体需求选择适合的线程模型,例如线程池...

    java socket 编程文档

    总结,Java Socket编程是构建网络应用的关键技术。通过理解Socket的工作原理,掌握创建、连接、通信和关闭的基本步骤,以及处理异常和优化性能的方法,开发者可以构建出健壮且高效的网络应用程序。

    java socket 网络五子棋

    Java Socket网络五子棋是一款基于Java编程语言,利用Socket通信技术实现的在线对战游戏。在这款游戏中,玩家可以通过互联网进行实时的五子棋对决,享受远程竞技的乐趣。本项目的核心在于Socket编程,它允许两个远程...

    java socket查询数据库实现登录验证

    在Java编程领域,Socket通信是一种基础且重要的网络编程技术,常用于实现客户端-服务器应用程序间的双向通信。在这个特定的场景中,我们利用Java Socket来实现一个登录验证系统,该系统会通过查询数据库来验证用户的...

    java socket 实现SMTP协议 发送邮件.docx

    Java Socket 实现 SMTP 协议发送邮件 Java Socket 是 Java 语言中用于实现网络编程的 API,通过 Socket,可以实现与远程服务器的通信。在这里,我们将使用 Java Socket 实现 SMTP 协议来发送邮件。 SMTP 协议简介 ...

    Java Socket发送和接收的例子

    总结来说,Java Socket编程是构建网络应用程序的关键技术,它允许Java应用程序与其他网络上的应用程序进行双向通信。通过ServerSocket和Socket类,我们可以建立连接,交换数据,从而实现丰富的网络功能。

    java socket传输各种格式文件

    总结,Java Socket提供了一种强大且灵活的方式来进行文件传输。通过理解Socket的基本概念,结合文件流操作,我们可以构建出高效、安全的文件传输系统。在实际应用中,还需要考虑网络环境、错误处理、安全性等多个...

    Java Socket实现简单的聊天程序

    总结来说,Java Socket实现的简易聊天程序是一个基础的网络通信示例,它展示了如何使用Socket进行数据交换,适用于初学者理解网络编程的基本原理。随着技能的提升,可以在此基础上添加更多的功能和优化,构建更完善...

    Java Socket实战之二 多线程通信 .

    本篇主要探讨的是如何在Java中实现多线程通信,利用Socket技术构建高效的并发服务器。我们将结合"Java Socket实战之二 多线程通信"这篇博文进行深入解析。 首先,了解Socket的基本概念。Socket在计算机网络中扮演着...

    通过java socket实现屏幕网络监控

    Java Socket技术是网络编程中的重要组成部分,主要用于实现两个应用程序之间的通信。在这个场景中,我们讨论的是如何使用Java Socket来实现实时的屏幕监控功能,即服务端能够远程查看客户端的屏幕内容,这样的功能在...

    java socket开发即时通讯服务器

    Java Socket 开发即时通讯服务器是构建实时通信系统的关键技术之一,尤其在企业级应用、在线游戏、聊天室等场景中广泛应用。本篇将深入探讨Java Socket在即时通讯服务器开发中的核心概念、步骤以及关键技术。 首先...

    flash as3/java socket 聊天室

    标题中的“flash as3/java socket 聊天室”指的是使用Adobe Flash ActionScript 3(AS3)语言和Java的Socket编程技术实现的一个在线聊天应用程序。这个应用允许用户通过网络进行实时通信,创建一个基本的聊天环境。...

    java_chatroom.rar_java socket _java socket 聊天_java 聊天

    Java Socket编程是网络通信的核心技术之一,主要用于实现两台计算机之间的数据传输。在这个"java_chatroom.rar"压缩包中,包含了一个基于Java Socket实现的简单聊天室应用,它由两个主要部分组成:客户端...

    java socket聊天程序,有界面

    总结来说,Java Socket聊天程序通过Java的网络编程接口实现了多用户间的点对点通讯,提供了丰富的用户界面,让用户可以方便地进行聊天交流。这样的程序设计不仅涉及网络编程,还涉及到GUI设计、多线程编程以及可能的...

    史上最全的Java核心技术总结.pdf

    Java核心技术总结 Java是一种面向对象的编程语言,它的核心技术包括Java虚拟机(JVM)、Java核心技术、Java并发编程、计算机网络等。以下是Java核心技术的总结: 一、Java虚拟机(JVM) Java虚拟机(JVM)是Java ...

    java socket多线程文件传输实例项目

    总结来说,Java Socket多线程文件传输实例项目是一个综合性的实践,涵盖了网络编程、多线程并发控制以及文件I/O等多个核心Java技术。通过这个项目,开发者可以深入理解如何在实际场景中运用这些技术,解决并发文件...

    JavaTCP-Socket.zip_JAVA socket编程_java socket _socket 聊天

    Java TCP套接字编程是网络通信中的核心...总结,Java Socket编程为开发者提供了构建网络通信应用的基础工具,通过TCP套接字,我们可以创建可靠的聊天应用。理解并熟练掌握Socket编程,是开发网络应用程序的关键步骤。

    java程序socket编程示例代码

    Java程序socket编程示例代码 ...Java程序socket编程是一种强大的网络编程技术,能够实现客户机和服务器端之间的可靠通信。通过本文,我们学习了Java程序socket编程的基本概念和实现方法,并总结出了一些重要的知识点。

    java实现简单socket通信

    Java实现的简单Socket通信是网络编程中的基础技术,主要用于设备间的双向数据传输。在这个场景中,我们有两个窗口,一个作为服务器端,另一个作为客户端,它们通过TCP协议进行通信。TCP是一种面向连接的、可靠的传输...

Global site tag (gtag.js) - Google Analytics