简体   繁体   中英

TCP how to send/receive real-time large packets in Java?

I have this TCP server running Because UDP server was able to accept large packets but ISP blocks my UDP packets even i have Public IP and Static services. But now decided to change it to TCP but i have a large stack now to replace with UDP to TCP.

Here is the server which is running but it does not at once receive a large packet, how can i increase it to unlimited or maximum size or etc?

1) Is there any way with this?

public void run() 
{
    while(true) 
    {
        byte[] buf=new byte[5024]; <<< not helping!!
        int bytes_read = 0;
        try {                                
            bytes_read = sockInput.read(buf, 0, buf.length);                  
            String data = null;
            data = new String(buf, 0, bytes_read);                   
            System.out.println("[TCP]: incomeing data: " +  bytes_read + " bytes, data=" +data);
     }
 }

2) Is there any way with this?

public TCPHandler(Socket sock) throws IOException 
{
    sock.setReceiveBufferSize(10*1024 +1024); //<<<<< not helping !!!
    sock.setSendBufferSize(10*1024+1024);
    this.sock = sock;
    sockInput = sock.getInputStream();
    sockOutput = sock.getOutputStream();
    this.myThread = new Thread(this);
}

None is allowing me to handle large so that i can switch from UDP to TCP. Any ideas!!

TCP and UDP are different. TCP is not a packet-based protocol, it is a stream based protocol. Your data will arrive in order, and un-corrupted, but it will not necessarily all arrive at once.

What you should do is prefix each set 'packet' with a length. When you receive data, first read the length value, and then continue reading chunks from the socket until you have the amount of data required.

You shouldn't care how TCP splits your messages into packets and how many times you must read to get a full message. Just read until the end of the message has been reached, and then return all the bytes of the message.

Knowing when the message has been read completely depends on your protocol. You could choose to send only one message per connection, or you could send the length of the message before the message, or use some marker byte.

Note that you shouldn't use new String(byte[]) without specifying an encoding (and use the same when calling String.getBytes() ), especially if you transfer from one machine to another, since both machines could have a different default encoding.

The trouble you're having is how InputStreams work. When you call read(buf,offset,length) it doesn't always read length bytes everytime. It simply reads what is available() on the InputStream, and returns the number of bytes it read. So you need to continue to call read until you've actually read length bytes.

int len = 0;
int expectedLength = sockInput.readInt();
byte[] buf = new byte[ expectedLength ];
while( len != buf.length ) {
   len += sockInput.read( buf, len, buf.length );
}

// now you have a buffer with expectedLength data in it.

You can also look at using DataInputStream.readFully() by wrapping your

DataInputStream ds = new DataInputStream( sock.getInputStream() );
ds.readFully( buf, 0, buf.length );

http://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html

But if you're really just after a String you should do this:

Reader reader = new InputStreamReader( sockInput.getInputStream(), "UTF-8" );

Same rules for read( char[], offset, length ) as read( byte[], offset, length )

A TCP is a stream of bytes you can get a portion of, one or more messages is a single read. With UDP packets of more than 532 bytes, the packet can be broken up, so you have the same potential problem.

A simple way to encode message is to send the length first.

 final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
 final DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

 public void writeMessage(String text) {
    out.writeUTF(text);
 }

 public String readMessage() {
    return in.readUTF();
 }

read/write UTF sends the length first and followed by the content

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM