import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.Socket;
private static Socket dataSocket;
private static DataInputStream socketDataIn;
private static DataOutputStream socketDataOut;
dataSocket = new Socket("172.16.18.1",1888);
dataSocket.setSoTimeout(5000);
dataSocket.setReceiveBufferSize(8192); //这个好象没起作用
socketDataIn = new DataInputStream(dataSocket.getInputStream());
socketDataOut= new DataOutputStream(dataSocket.getOutputStream());
socketDataOut.write(outDataBuff,0,2049);//大于2048的部分收不到
...
int pLength = socketDataIn.read(inDataBuff);
-------------------------------------------------------------------------
我的问题就是当发送超过2048个字节时,SOCKET另外一端收不全,必须再read一次。而我认为这个机制应该是由TCP层提供的,其他的工具C(UNIX)和DELHPI(WINDOWS)均无此问题。难道是JAVA的?
欢迎大家来讨论!
11 个解决方案
#1
socketDataOut.flush();
底层发送都存在一个最小尺度问题,如512字节满了才自动发送,而你的代码刚好不够,所以不会引发自动发送
底层发送都存在一个最小尺度问题,如512字节满了才自动发送,而你的代码刚好不够,所以不会引发自动发送
#2
我的问题出在socket的in上,是read读不到完整的包。这里的包长度是指我们在应用层上的定义,跟底层的无关。底层会帮我们实现差错控制。
#3
是不是这里啊?
dataSocket.setSendBufferSize(8192);
或者是catch一下io的exception.........
dataSocket.setSendBufferSize(8192);
或者是catch一下io的exception.........
#4
DATAOUTPUTSTREM 之类的是发送UNICODE,所以。。。。
#5
这部分的原因应该是如borz所说,与流的限制有关。与JAVA的SOCKET机制无关。
发送是0x1001个字节
接收是0x1002个字节
那么大家继续讨论,在这种情况下,难道要我们自己来做底层的工作吗?大家有什么好办法
发送是0x1001个字节
接收是0x1002个字节
那么大家继续讨论,在这种情况下,难道要我们自己来做底层的工作吗?大家有什么好办法
#6
错了!是在SOCKET的socketOptions里 /**
* Set a hint the size of the underlying buffers used by the
* platform for outgoing network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be sent over the socket. When
* used in get, this must return the size of the buffer actually
* used by the platform when sending out data on this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setSendBufferSize
* @see Socket#getSendBufferSize
* @see DatagramSocket#setSendBufferSize
* @see DatagramSocket#getSendBufferSize
*/
public final static int SO_SNDBUF = 0x1001;
/**
* Set a hint the size of the underlying buffers used by the
* platform for incoming network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be received over the
* socket. When used in get, this must return the size of the
* buffer actually used by the platform when receiving in data on
* this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setReceiveBufferSize
* @see Socket#getReceiveBufferSize
* @see DatagramSocket#setReceiveBufferSize
* @see DatagramSocket#getReceiveBufferSize
*/
public final static int SO_RCVBUF = 0x1002;
* Set a hint the size of the underlying buffers used by the
* platform for outgoing network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be sent over the socket. When
* used in get, this must return the size of the buffer actually
* used by the platform when sending out data on this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setSendBufferSize
* @see Socket#getSendBufferSize
* @see DatagramSocket#setSendBufferSize
* @see DatagramSocket#getSendBufferSize
*/
public final static int SO_SNDBUF = 0x1001;
/**
* Set a hint the size of the underlying buffers used by the
* platform for incoming network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be received over the
* socket. When used in get, this must return the size of the
* buffer actually used by the platform when receiving in data on
* this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setReceiveBufferSize
* @see Socket#getReceiveBufferSize
* @see DatagramSocket#setReceiveBufferSize
* @see DatagramSocket#getReceiveBufferSize
*/
public final static int SO_RCVBUF = 0x1002;
#7
拉一拉,敬请关注
#8
to airwing
我还是觉得与底层有关,因为setReceiveBuffer只是告诉JAVA系统设定一种缓冲机制
但数据总是要发送到网络上的。在物理层,存在一个最小发送长度,如通过ATM传送时好象是512个字节,你可以看看有关书籍,自然明白底层的运作
我还是觉得与底层有关,因为setReceiveBuffer只是告诉JAVA系统设定一种缓冲机制
但数据总是要发送到网络上的。在物理层,存在一个最小发送长度,如通过ATM传送时好象是512个字节,你可以看看有关书籍,自然明白底层的运作
#9
to kz
和物理层无关,任何应用层数据都会在IP层被分割层多个IP包,由TCP层负责传输和顺序、差错控制。难道各位做程序都只发512字节吗?
和物理层无关,任何应用层数据都会在IP层被分割层多个IP包,由TCP层负责传输和顺序、差错控制。难道各位做程序都只发512字节吗?
#10
关注关注,我也想知道怎么回事,提一提
我也帮你问一问
我也帮你问一问
#11
to airwing
是这样,例如TCP层发送数据513个字节,但你的网卡与下一个节点如中继器的通信有一个最小发送单位--比方512个字节。当TCP层flush()时物理层即网卡发送了两个数据包:一个512个字节;另一个也是512个字节(但只包含一个有用数据。当从另一端接收时,第一次read将512个字节放入了你的缓冲区(注意:接收必须是以数据包为单位),所以你必须再read一次
是这样,例如TCP层发送数据513个字节,但你的网卡与下一个节点如中继器的通信有一个最小发送单位--比方512个字节。当TCP层flush()时物理层即网卡发送了两个数据包:一个512个字节;另一个也是512个字节(但只包含一个有用数据。当从另一端接收时,第一次read将512个字节放入了你的缓冲区(注意:接收必须是以数据包为单位),所以你必须再read一次
#1
socketDataOut.flush();
底层发送都存在一个最小尺度问题,如512字节满了才自动发送,而你的代码刚好不够,所以不会引发自动发送
底层发送都存在一个最小尺度问题,如512字节满了才自动发送,而你的代码刚好不够,所以不会引发自动发送
#2
我的问题出在socket的in上,是read读不到完整的包。这里的包长度是指我们在应用层上的定义,跟底层的无关。底层会帮我们实现差错控制。
#3
是不是这里啊?
dataSocket.setSendBufferSize(8192);
或者是catch一下io的exception.........
dataSocket.setSendBufferSize(8192);
或者是catch一下io的exception.........
#4
DATAOUTPUTSTREM 之类的是发送UNICODE,所以。。。。
#5
这部分的原因应该是如borz所说,与流的限制有关。与JAVA的SOCKET机制无关。
发送是0x1001个字节
接收是0x1002个字节
那么大家继续讨论,在这种情况下,难道要我们自己来做底层的工作吗?大家有什么好办法
发送是0x1001个字节
接收是0x1002个字节
那么大家继续讨论,在这种情况下,难道要我们自己来做底层的工作吗?大家有什么好办法
#6
错了!是在SOCKET的socketOptions里 /**
* Set a hint the size of the underlying buffers used by the
* platform for outgoing network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be sent over the socket. When
* used in get, this must return the size of the buffer actually
* used by the platform when sending out data on this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setSendBufferSize
* @see Socket#getSendBufferSize
* @see DatagramSocket#setSendBufferSize
* @see DatagramSocket#getSendBufferSize
*/
public final static int SO_SNDBUF = 0x1001;
/**
* Set a hint the size of the underlying buffers used by the
* platform for incoming network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be received over the
* socket. When used in get, this must return the size of the
* buffer actually used by the platform when receiving in data on
* this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setReceiveBufferSize
* @see Socket#getReceiveBufferSize
* @see DatagramSocket#setReceiveBufferSize
* @see DatagramSocket#getReceiveBufferSize
*/
public final static int SO_RCVBUF = 0x1002;
* Set a hint the size of the underlying buffers used by the
* platform for outgoing network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be sent over the socket. When
* used in get, this must return the size of the buffer actually
* used by the platform when sending out data on this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setSendBufferSize
* @see Socket#getSendBufferSize
* @see DatagramSocket#setSendBufferSize
* @see DatagramSocket#getSendBufferSize
*/
public final static int SO_SNDBUF = 0x1001;
/**
* Set a hint the size of the underlying buffers used by the
* platform for incoming network I/O. When used in set, this is a
* suggestion to the kernel from the application about the size of
* buffers to use for the data to be received over the
* socket. When used in get, this must return the size of the
* buffer actually used by the platform when receiving in data on
* this socket.
*
* Valid for all sockets: SocketImpl, DatagramSocketImpl
*
* @see Socket#setReceiveBufferSize
* @see Socket#getReceiveBufferSize
* @see DatagramSocket#setReceiveBufferSize
* @see DatagramSocket#getReceiveBufferSize
*/
public final static int SO_RCVBUF = 0x1002;
#7
拉一拉,敬请关注
#8
to airwing
我还是觉得与底层有关,因为setReceiveBuffer只是告诉JAVA系统设定一种缓冲机制
但数据总是要发送到网络上的。在物理层,存在一个最小发送长度,如通过ATM传送时好象是512个字节,你可以看看有关书籍,自然明白底层的运作
我还是觉得与底层有关,因为setReceiveBuffer只是告诉JAVA系统设定一种缓冲机制
但数据总是要发送到网络上的。在物理层,存在一个最小发送长度,如通过ATM传送时好象是512个字节,你可以看看有关书籍,自然明白底层的运作
#9
to kz
和物理层无关,任何应用层数据都会在IP层被分割层多个IP包,由TCP层负责传输和顺序、差错控制。难道各位做程序都只发512字节吗?
和物理层无关,任何应用层数据都会在IP层被分割层多个IP包,由TCP层负责传输和顺序、差错控制。难道各位做程序都只发512字节吗?
#10
关注关注,我也想知道怎么回事,提一提
我也帮你问一问
我也帮你问一问
#11
to airwing
是这样,例如TCP层发送数据513个字节,但你的网卡与下一个节点如中继器的通信有一个最小发送单位--比方512个字节。当TCP层flush()时物理层即网卡发送了两个数据包:一个512个字节;另一个也是512个字节(但只包含一个有用数据。当从另一端接收时,第一次read将512个字节放入了你的缓冲区(注意:接收必须是以数据包为单位),所以你必须再read一次
是这样,例如TCP层发送数据513个字节,但你的网卡与下一个节点如中继器的通信有一个最小发送单位--比方512个字节。当TCP层flush()时物理层即网卡发送了两个数据包:一个512个字节;另一个也是512个字节(但只包含一个有用数据。当从另一端接收时,第一次read将512个字节放入了你的缓冲区(注意:接收必须是以数据包为单位),所以你必须再read一次