您的位置:

java套接字,java套接字连不上

本文目录一览:

java聊天程序套接字错误求高手

我已前碰到过.

这个是说端口已使用.Address already in use:JVM_Bind.

通常是先确认一下有没有其他的软件使用这个端口,如果是自己开发的Socket,通常不会这么巧的.

如果没有其他软件占用的话,就是另一个很常见的情况.就是说Socket程序中的socket每次在结束关闭之后的几秒或几十秒内通常是还没有关闭的.这是因为如果Socket立刻关闭,而碰巧又有其他的软件马上使用了这个端口时,就会接收到原本应该由前面socket接收的数据.这就是不允许的数据.所以socket被关闭以后,还是会在后台将客户发过来的数据接收完才真正关闭.

版主所说,可能是在关闭程序以后,马上又再运行此程序,导致出现了端口冲突.

对于此种问题,是JAVA语言的一种高级特性,可能没办法改.最好是刷新一下,并稍等片刻再重新运行.

JAVA中什么是套接字???

你打电话需要有电话或手机吧?套接字就是手机。

你打的,你就是主叫方,对方就是被叫方。那么你需要一个Socket,对方需要一个ServerSocket。

被叫方有多个号。他得选中一个号工作,这叫绑定。在套接字上,是绑定到端口。

对方需要开机才能接听电话。那他就得先侦听。ServerSocket的accept()就是开始侦听,并有来电时接听。

Java中socket填的ip

首先必须明确:TCP/IP模型中有四层结构:

应用层(Application Layer)、传输层(Transport Layer)、网络层(Internet Layer )、链路层(LinkLayer)

其中Ip协议(Internet Protocol)是位于网络层的,TCP协议时位于传输层的。通过Ip协议可以使可以使两台计算机使用同一种语言,从而允许Internet上连接不同类型的计算机和不同操作系统的网络。Ip协议只保证计算机能够接收和发送分组数据。 当计算机要和远程的计算机建立连接时,TCP协议会让他们建立连接:用于发送和接收数据的虚拟电路。

在JAVA中,我们用 ServerSocket、Socket类创建一个套接字连接,从套接字得到的结果是一个InputStream以及OutputStream对象,以便将连接作为一个IO流对象对待。通过IO流可以从流中读取数据或者写数据到流中,读写IO流会有异常IOException产生。

套接字或插座(socket)是一种软件形 式的抽象,用于表达两台机器间一个连接的“终端”。针对一个特定的连接,每台机器上都有一个“套接字”,可以想象它们之间有一条虚拟的“线缆”。JAVA 有两个基于数据流的套接字类:ServerSocket,服务器用它“侦听”进入的连接;Socket,客户端用它初始一次连接。侦听套接字只能接收新的 连接请求,不能接收实际的数据包,即ServerSocket不能接收实际的数据包。

套接字是基于TCP/IP实现的,它是用来提供一个访问TCP的服务接口,或者说套接字socket是TCP的应用编程接口API,通过它应用层就可以访问TCP提供的服务。

在JAVA中,我们用 ServerSocket、Socket类创建一个套接字连接,从套接字得到的结果是一个InputStream以及OutputStream对象,以便 将连接作为一个IO流对象对待。通过IO流可以从流中读取数据或者写数据到流中,读写IO流会有异常IOException产生。

套接字底层是基于TCP的,所以socket的超时和TCP超时是相同的。下面先讨论套接字读写缓冲区,接着讨论连接建立超时、读写超时以及JAVA套接字编程的嵌套异常捕获和一个超时例子程序的抓包示例。

1 socket读写缓冲区

一旦创建了一个套接字实例,操作系统就会为其分配缓冲区以存放接收和要发送的数据。

JAVA可以设置读写缓冲区的大小-setReceiveBufferSize(int size), setSendBufferSize(int size)。

向输出流写数据并不意味着数据实际上已经被发送,它们只是被复制到了发送缓冲区队列SendQ,就是在Socket的OutputStream上调用 flush()方法,也不能保证数据能够立即发送到网络。真正的数据发送是由操作系统的TCP协议栈模块从缓冲区中取数据发送到网络来完成的。

当有数据从网络来到时,TCP协议栈模块接收数据并放入接收缓冲区队列RecvQ,输入流InputStream通过read方法从RecvQ中取出数据。

2 socket连接建立超时

socket连接建立是基于TCP的连接建立过程。TCP的连接需要通过3次握手报文来完成,开始建立TCP连接时需要发送同步SYN报文,然后等待确认 报文SYN+ACK,最后再发送确认报文ACK。TCP连接的关闭通过4次挥手来完成,主动关闭TCP连接的一方发送FIN报文,等待对方的确认报文;被 动关闭的一方也发送FIN报文,然等待确认报文。

正在等待TCP连接请求的一端有一个固定长度的连接队列,该队列中的连接已经被TCP接受(即三次握手已经完成),但还没有被应用层所接受。TCP接受一个连接是将其放入这个连接队列,而应用层接受连接是将其从该队列中移出。应用层可以通过设置backlog变量来指明该连接队列的最大长度,即已被TCP接受而等待应用层接受的最大连接数。

当一个连接请求SYN到达时,TCP确定是否接受这个连接。如果队列中还有空间,TCP模块将对SYN进行确认并完成连接的建立。但应用层只有在三次握手中的第三个报文收到后才会知道这个新连接。如果队列没有空间,TCP将不理会收到的SYN。

如果应用层不能及时接受已被TCP接受的连接,这些连接可能占满整个连接队列,新的连接请求可能不被响应而会超时。如果一个连接请求SYN发送后,一段时间后没有收到确认SYN+ACK,TCP会重传这个连接请求SYN两次,每次重传的时间间隔加倍,在规定的时间内仍没有收到SYN+ACK,TCP将放弃这个连接请求,连接建立就超时了。

JAVA Socket连接建立超时和TCP是相同的,如果TCP建立连接时三次握手超时,那么导致Socket连接建立也就超时了。可以设置Socket连接建立的超时时间-

connect(SocketAddress endpoint, int timeout)

如果在timeout内,连接没有建立成功,在TimeoutException异常被抛出。如果timeout的值小于三次握手的时间,那么Socket连接永远也不会建立。

不同的应用层有不同的连接建立过程,Socket的连接建立和TCP一样-仅仅需要三次握手就完成连接,但有些应用程序需要交互很多信息后才能成功建立连接,比如Telnet协议,在TCP三次握手完成后,需要进行选项协商之后,Telnet连接才建立完成。

3 socket读超时

如果输入缓冲队列RecvQ中没有数据,read操作会一直阻塞而挂起线程,直到有新的数据到来或者有异常产生。调用setSoTimeout(int timeout)可以设置超时时间,如果到了超时时间仍没有数据,read会抛出一个SocketTimeoutException,程序需要捕获这个异 常,但是当前的socket连接仍然是有效的。

如果对方进程崩溃、对方机器突然重启、网络断开,本端的read会一直阻塞下去(由前面可知:双方要关闭连接需要四次挥手 .对方机重启或断开只是对方机的TCP连接关闭,本端的TCP连接还没关闭,所以本端机会一直阻塞),这时设置超时时间是非常重要的,否则调用read的线程会一直挂起。

TCP模块把接收到的数据放入RecvQ中,直到应用层调用输入流的read方法来读取。如果RecvQ队列被填满了,这时TCP会根据滑动窗口机制通知 对方不要继续发送数据,本端停止接收从对端发送来的数据,直到接收者应用程序调用输入流的read方法后腾出了空间。

4 socket写超时

socket的写超时是基于TCP的超时重传。超时重传是TCP保证数据可靠性传输的一个重要机制,其原理是在发送一个数据报文后就开启一个计时器,在一 定时间内如果没有得到发送报文的确认ACK,那么就重新发送报文。如果重新发送多次之后,仍没有确认报文,就发送一个复位报文RST,然后关闭TCP连 接。首次数据报文发送与复位报文传输之间的时间差大约为9分钟,也就是说如果9分钟内没有得到确认报文,就关闭连接。但是这个值是根据不同的TCP协议栈 实现而不同。

如果发送端调用write持续地写出数据,直到SendQ队列被填满。如果在SendQ队列已满时调用write方法,则write将被阻塞,直到 SendQ有新的空闲空间为止,也就是说直到一些字节传输到了接收者套接字的RecvQ中。如果此时RecvQ队列也已经被填满,所有操作都将停止,直到 接收端调用read方法将一些字节传输到应用程序。

当Socket的write发送数据时,如果网线断开、对端进程崩溃或者对端机器重启动,(由前面可知:双方要关闭连接需要四次挥手 .对端进程崩溃或者对端机器重启动只是对方机的TCP连接关闭,本端的TCP连接还没关闭,所以本端机会一直阻塞)TCP模块会重传数据,最后超时而关闭连接。下次如再调用write会导致一个异常而退出。

Socket写超时是基于TCP协议栈的超时重传机制,一般不需要设置write的超时时间,也没有提供这种方法。

5 双重嵌套异常捕获

如果ServerSocket、Socket构造失败,只需要仅仅捕获这个构造失败异常而不需要调用套接字的close方法来释放资源(必须保证构造失败 后不会留下任何需要清除的资源),因为这时套接字内部资源没有被成功分配。如果构造成功,必须进入一个try finally语句块里调用close释放套接字。请参照下面例子程序。

import java.net.*;

import java.io.*;

public class SocketClientTest

{

public static final int PORT = 8088;

public static void main( String[] args ) throws Exception

{

InetAddress addr = InetAddress.getByName( "127.0.0.1" );

Socket socket = new Socket();

try

{

socket.connect( new InetSocketAddress( addr, PORT ), 30000 );

socket.setSendBufferSize(100);

BufferedWriter out = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) );

int i = 0;

while( true )

{

System.out.println( "client sent --- hello *** " + i++ );

out.write( "client sent --- hello *** " + i );

out.flush();

Thread.sleep( 1000 );

}

}

finally

{

socket.close();

}

}

}

import java.io.*;

import java.net.ServerSocket;

import java.net.Socket;

public class SocketServerTest

{

public static final int PORT = 8088;

public static final int BACKLOG = 2;

public static void main( String[] args ) throws IOException

{

ServerSocket server = new ServerSocket( PORT, BACKLOG );

System.out.println("started: " + server);

try

{

Socket socket = server.accept();

try

{

BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream() ) );

String info = null;

while( ( info = in.readLine() ) != null )

{

System.out.println( info );

}

}

finally

{

socket.close();

}

}

finally

{

server.close();

}

}

}

Java网络编程如何初始化套接字

不同的构造方法不仅带的参数不同,所具有的意义也不一样。下面分别解析这两个类的实例初始化过程。 ServerSocket 实例的初始化 ServerSocket 类提供了四个构造器: public Socket(String host, int port) throws UnknownHostException, IOException public Socket(InetAddress address, int port) throws IOException public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException public Socket() public Socket(Proxy proxy) 带参构造器用来创建已绑定的服务器套接字,也就是说构造成功后它就已经开始侦听指定的端口,且能够调用 accept() 方法来接受客户端连接。默认构造器则会创建未绑定的服务器套接字,构造成功后必须手动将其绑定到一个本地地址才能用,在绑定之前可以进行一些选项配置。 带参构造器 总的来说,带参构造器提供了三个参数: port 指定该服务器套接字所要侦听的本地端口。如果为 0,则由系统自动分配一个端口号,这必须以另外的方式让客户端获取端口号。 backlog 这个名词目前还没有合适的译名。底层系统的 TCP 实现会维护一个连接队列,该队列缓存了已被 TCP 处理完毕,但还没有被服务器套接字接受的客户端连接。一旦某个连接被接受(通过调用 accept() 方法),它就会被从队列中移除。backlog 参数就用于指定队列的最大长度,默认值为 50,但这个值只是一个建议,底层系统可能根据需要自动调整。如果队列满了,则其行为是平台相关的:微软的 WINSOCK 会拒绝新的连接,其他实现则什么都不做。严格地说,微软没有遵守规范,破坏了游戏规则…… bindAddr 一台机器可能会有多个本地 IP 地址,例如同时使用多块网卡。使用其他两个带参构造器时,该参数为 null,服务器套接字会在所有的本地 IP 地址(0.0.0.0 或 ::0)上侦听。如果希望只侦听一个地址,则可使用该参数。 默认构造器 如果使用默认构造器,在绑定地址前,还可以做些配置。绑定操作由两个 bind 方法定义,参数类似于带参构造器。配置项包括以下方面(都必须在绑定前配置): 设置是否重用本地地址 该选项由 setReuseAddress(boolean on) 方法配置,对应底层系统的 SO_REUSEADDR 套接字选项。JDK 没有定义该选项的默认值。如果该选项为 false,则在关闭 TCP 连接时,为了保证可靠性,该连接可能在关闭后的一段时间(大约两分钟)内保持超时状态(通常称为 TIME_WAIT 状态或 2MSL 等待状态),这段时间里无法将新建的服务器套接字绑定到同一个地址。在开发阶段,服务器可能不断重启,打开改选项会非常有用。 设置接收缓冲区大小 该选项由 setReceiveBufferSize(int size) 方法配置,对应底层系统的 SO_RCVBUF 套接字选项,单位是字节。《RFC 1323 - TCP Extensions for High Performance》将缓冲区大小定义为 64KB。该选项只是一个建议值,底层系统可能根据需要自行调整。 设置超时值 该选项由 setSoTimeout(int timeout) 方法配置,对应底层系统的 SO_TIMEOUT 套接字选项,单位是毫秒。默认值为 0。该选项影响 accept 方法的阻塞时间长度,如果超时将引发 SocketTimeoutException。如果设为 0,则表示永不超时。 设置性能首选项 性能首选项包括连接时间、延迟和带宽三个选项,由 setPerformancePreferences(int connectionTime, int latency, int bandwidth) 方法配置。这三个数值分别表示短连接时间、低延迟和高带宽的相对重要性,数值越大则越重要;其各自的绝对值没有意义。该方法的初衷是为了让 Java 能在用非 TCP/IP 实现的套接字环境下工作得更好,某些需要对网络进行调优的程序也可以将这三个首选项作为配置参数提供给用户。 Socket 实例的初始化 Socket 类提供了六个公共构造器(已过时的除外): public Socket(String host, int port) throws UnknownHostException, IOException public Socket(InetAddress address, int port) throws IOException public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException public Socket() public Socket(Proxy proxy) 前四个构造器创建已连接的客户端套接字,也就是说构造的时候就会去连接服务器。前两个构造器需要提供服务器的地址和端口作为参数,本地地址和端口由系统自动分配;后两个允许手动指定本地地址和端口,但极少使用。后两个构造器创建未连接的套接字,创建后需要调用 connect 方法手动连接,连接之前可以做一些配置。最后一个构造器接受一个代表代理服务其的 Proxy 对象,JDK 支持 HTTP 和 SOCKS(V4 或 V5)两种代理类型。 连接前的配置 在连接前,客户端套接字不仅像服务器套接字那样可以设置是否重用本地地址、缓冲区大小、超时值和性能首选项,还能够配置以下各项(都必须在连接前配置): 设置是否保持活跃 该选项由 setKeepAlive(boolean on) 方法配置,对应底层系统的 SO_KEEPALIVE 套接字选项。默认值为 false。如果打开该选项,则套接字会定期自动发送保持活跃的探测性消息,类似于心跳检测。根据《RFC 1122 - Requirements for Internet Hosts》的规定,保持活跃机制只是 TCP 的一个可选功能,如果支持的话,默认必须为 false,而且这种机制默认在成功建立连接后,且连续两小时没有数据传输的情况下才会被激活。从另一方面来看,通过套接字的 I/O 操作完全可以知道连接是否还有效,所以该选项的实用价值不大。 设置是否收发带外数据 该选项由 setOOBInline(boolean on) 方法配置,对应底层系统的 SO_OOBINLINE 套接字选项。默认值为 off。带外数据(Out-of-band Data)也叫做紧急数据,表示数据很重要,需要使用不同于发送普通数据的一个专用通道来发送。打开该选项后,就可以调用 sendUrgentData(int data) 方法发送一个字节的紧急数据。JDK 对带外数据只提供了有限支持,紧急数据将会和普通数据一起被收到,并且无法自动区分。该选项对应用开发人员意义不大。 设置是否从容关闭连接 该选项由 setSoLinger(boolean on, int linger) 方法配置,对应底层系统的 SO_LINGER 套接字选项。默认为 false。该选项只会影响套接字的关闭,其中的 linger 参数表示超时时间,单位为秒。如果打开改选项:如果将 linger 设为 0,则关闭套接字的时候,未发送的数据会被丢弃,且另一端会出现连接被同位体重置的异常;如果 linger 非 0,则关闭套接字的线程将被阻塞,直到数据全部发送或超时,超时后的行为与底层系统相关,JDK 无法控制。如果关闭该选项,则套接字正常关闭,数据也会全部发送。由于底层实现的差异性,不提倡应用开发人员打开该选项。 设置是否延迟发送数据 该选项由 setTcpNoDelay(boolean on) 方法配置,对应底层系统的 TCP_NODELAY TCP 选项。默认值为 off。打开该选项将禁用 Nagle 算法,TCP 包会立即发送;关闭该选项则会启用 Nagle 算法,多个较小的 TCP 包会被组合成一个大包一起发送,虽然发送延迟了,但有利于避免网络拥塞。默认为 false。该选项对实时性很强的程序可能有用,但一般的程序不需要关心。 设置流量类别 该选项由 setTrafficClass(int tc) 方法配置,对应底层系统的“流量类别”套接字属性。该选项用于向网络(例如路由器)提示从该套接字发送的包需要获取哪些服务类型,对本地 TCP 协议栈没有影响。IPv4 和 IPv6 分别定义了多个不同的值,例如 IPv4 将 0x08 定义为最大吞吐量,0x10 定义为最小延迟,等等。可以用或运算将多个值合并为一个选项。该选项用来调整性能,需要根据实际情况设置。由于只是建议值,可能被网络忽略。

java套接字,java套接字连不上

2022-11-28
java套接字,java套接字 数据粘连

2023-01-09
java连接字符串,java字符连接成字符串

2023-01-03
发篇java复习笔记(java课程笔记)

2022-11-09
jsp使用java连接数据库(jsp连接数据库的方法)

本文目录一览: 1、怎么使用JAVA连接数据库? 2、怎么用jsp连接mysql数据库 3、在JSP页面中实现连接数据库与在Java程序中实现连接数据库有什么区别? 4、java 中 怎样将JSP页面

2023-12-08
php套接字编程,网络编程套接字

2023-01-04
套接字的概念

2023-05-09
java笔记,大学java笔记

2022-11-28
重学java笔记,java笔记总结

2022-11-23
Java数据库连接,java 连接数据库

2023-01-04
java如何连接bw(java如何连接mysql)

2022-11-10
java笔记,尚硅谷java笔记

2022-12-01
数据库与java连接,数据库与java建立连接

2022-12-01
java笔试题,JAVA笔试题压缩字符串

2023-01-04
java学习的一些基础笔记(java初学笔记)

2022-11-14
java与数据库连接篇,数据库和java怎么连接

2022-11-21
java基础知识常思考(java基础知识点笔记)

2022-11-14
jsp中嵌套java(jsp嵌套页面)

本文目录一览: 1、在jsp 页面中,用嵌套Java代码的方式怎么取出struts2值栈中的对象 2、在JSP页面中,嵌入JAVA代码片段的语法格式是什么?声明的语法格式为什么? 3、jsp页面中ja

2023-12-08
mysql和java建立了连接,java的mysql连接

2022-11-21
java学习笔记(java初学笔记)

2022-11-14