Java Socket consumes 100% CPU when started receiving client request - java

I have a Socket that consumes 100% CPU, Single client always sends the data to server around 4096 bytes, at the server side I want to get client data & convert into actual form & store into database. Client sending data after every 3 Seconds. I did the following code to get client request.
ServerSocket waiting = new ServerSocket(18800, 50, InetAddress.getByName("192.20.50.102"));
while(true) {
Socket socket = waiting.accept();
new SessionHandler(socket).start();
}
Client code written in C so datatypes are different than Java because of that I need to convert received bytes into actual form & insert into database. Thread class code as per follows:
public class SessionHandler extends Thread {
private Socket socket;
public SessionHandler(Socket socket) {
this.socket = socket;
}
public void run() {
DataInputStream dataInputStream;
try {
dataInputStream = new DataInputStream(socket.getInputStream());
int tcCode = dataInputStream.readInt();
int length = dataInputStream.readInt();
if (tcCode == 1001) {
System.out.println("in 1001");
byte[] messageByte = new byte[length];
int totalBytesRead = 0;
while (totalBytesRead < length) {
int currentBytesRead = dataInputStream.read(messageByte, totalBytesRead, length - totalBytesRead);
totalBytesRead = currentBytesRead + totalBytesRead;
}
ByteBuffer buffer = ByteBuffer.wrap(messageByte);
ShortBuffer shortBuffer = buffer.asShortBuffer();
short[] values = new short[length / 2];
shortBuffer.get(values);
TCCodeOneOOOne tcCodeOneOOOne = new TCCodeOneOOOne(values);
tcCodeOneOOOne.main(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

try it as follow:
ServerSocket waiting = new ServerSocket(18800, 50, InetAddress.getByName("192.20.50.102"));
Socket socket = waiting.accept();
new SessionHandler(socket).start();

Related

Voip UDP adding a sequence number (preparing for packetloss)

Note: I'm currently learning UDP and how effective a VoIP system would be in comparison with a TCP system, I've already done TCP so please no one comment TCP is better etc..
So I'm trying to add a sequence number to the packets so I can order them on the server end and prepare for any lost packets, by repeating the previous for example
Problem: I read a stackoverflow that said using DataOutputStreams is a good way to go about this, so I implemented it. however when using the code dos.writeInt(sequenceNumber++); I get a horrible repetitive crackle. I was thinking maybe the problem is the amount of bytes that im sending.
Thank you in advance, any pointers will be great
boolean running = true;
try {
AudioRecorder recorder = new AudioRecorder();
int sequenceNumber = 0;
while (running) {
byte[] tempBuffer = recorder.getBlock();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.write(tempBuffer);
dos.writeInt(sequenceNumber++);
dos.flush();
DatagramPacket sendPacket = new DatagramPacket(baos.toByteArray(), baos.size(), clientIP, PORT);
sending_socket.send(sendPacket);
}
recorder.close();
} catch (Exception e) {
System.out.println("Error" + e);
Server end:
byte[] buffer = new byte[512];
byte[] temp = new byte[512];
try {
// CODE TO RECEIVE THE AUDIO
AudioPlayer player = new AudioPlayer();
int expectedValue = 0;
while (running) {
//Vector used to store audio blocks (32ms/512bytes each)
Vector<byte[]> voiceVector = new Vector<>();
// creates a new udp packet to receive the audio
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
receiving_socket.receive(packet);
// creates a byte array from the data
byte[] udpPacketBytes = packet.getData();
ByteArrayInputStream baos = new ByteArrayInputStream(udpPacketBytes);
DataInputStream dos = new DataInputStream(baos);
int receivedValue = dos.readInt();
if (receivedValue == expectedValue) {
byte[] filteredByteArray = Arrays.copyOfRange(udpPacketBytes, 4, udpPacketBytes.length - 4);
voiceVector.add(filteredByteArray);
Iterator<byte[]> voiceItr = voiceVector.iterator();
while (voiceItr.hasNext()) {
player.playBlock(voiceItr.next());
}
} else {
// play the previous again
byte[] filteredByteArray = Arrays.copyOfRange(temp, 4, temp.length - 4);
voiceVector.add(filteredByteArray);
Iterator<byte[]> voiceItr = voiceVector.iterator();
while (voiceItr.hasNext()) {
player.playBlock(voiceItr.next());
}
// play the current one
byte[] fba = Arrays.copyOfRange(udpPacketBytes, 4, udpPacketBytes.length - 4);
voiceVector.add(fba);
Iterator<byte[]> vItr = voiceVector.iterator();
while (vItr.hasNext()) {
player.playBlock(vItr.next());
}
}
System.out.println(receivedValue + " " + expectedValue);
expectedValue = receivedValue + 1;
temp = packet.getData();
}
} catch (Exception e) {
System.out.println("yo");
}
//Close the socket
receiving_socket.close();
You are writing the sequence number but you are not reading or removing it so your sequence number ends up in the audio.
I suggest you read the same format you write.

Can't run two threads in Java

I'm having trouble running these two threads in Java. I have two methods in the client class and in each method they both have a socket of different ports but when I run the client, i see the error for a split second of one of the threads but the other one that sends the file over works.
Any help?
ClientApp.java
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Thread getFileThread = new Thread() {
public void run() {
Client client = new Client();
try {
client.getTheFile("girlwithmask.jpg");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread getListOfFilesThread = new Thread() {
public void run() {
Client client = new Client();
ArrayList<String> listOfFiles = null;
try {
listOfFiles = client.getFileList();
System.out.println(listOfFiles.get(1));
notify();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
getListOfFilesThread.start();
getFileThread.start();
}
Client.java
public class Client {
private static final int PORT = 2665;
private static String HOST = "localhost";
Client() {
}
public void getTheFile(String filename) throws UnknownHostException, IOException {
filename = "girlwithmask.jpg"; ///this is temporary
int filesize = 5000000; //buffer size 5mb
int bytesRead;
int currentTotalNumberOfBytes = 0;
//connect to port on server - server waits for this after running socket.accept() in the Server class
Socket socket = new Socket(HOST, PORT);
byte[] byteArray = new byte[filesize]; //create a byte array of 5mb
InputStream inputStream = socket.getInputStream(); //channel to to server
FileOutputStream fileOutStream = new FileOutputStream("myClientFiles/" + filename);
BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
bytesRead = inputStream.read(byteArray, 0, byteArray.length);
currentTotalNumberOfBytes = bytesRead;
do { //read till the end and store total in bytesRead and add it to currentTotalNumberOfBytes
bytesRead = inputStream.read(byteArray, currentTotalNumberOfBytes, (byteArray.length - currentTotalNumberOfBytes));
if (bytesRead >= 0) {
currentTotalNumberOfBytes += bytesRead;
}
} while (bytesRead > -1); // when bytesRead == -1, there's no more data left and we exit the loop
bufferOutStream.write(byteArray, 0, currentTotalNumberOfBytes); //write the bytes to the file
bufferOutStream.flush();
bufferOutStream.close();
socket.close();
}
public ArrayList<String> getFileList() throws UnknownHostException, IOException, ClassNotFoundException {
Socket socket = new Socket("localhost", 9999);
ArrayList<String> titleList = new ArrayList<String>();
ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
Object object = objectInput.readObject();
titleList = (ArrayList<String>) object;
// System.out.println(titleList.get(2));
return titleList;
}
}
I'm not sure what is going on here. Been working with this for a couple of hours.
In the absence of an actual error, or indeed question, all we can do is critique your code:
byte[] byteArray = new byte[filesize]; //create a byte array of 5mb
You don't know what filesize is. You've hardcoded a guess of 5000000. This will not work for any case where the filesize is bigger than 5000000 which might be very often. There is an approach where you don't need to know the filesize: nor do you need a buffer the size of the whole file in the first place. You're assuming the file fits into memory and that the file length fits into an int. Both assumptions may be wrong. Use a smaller buffer size of 8192 or some such reasonable number which is usually a multiple of 1024 to get a good memory alignment. Hard-coding a big size of 5000000 has the drawbacks mentioned.
InputStream inputStream = socket.getInputStream(); //channel to to server
FileOutputStream fileOutStream = new FileOutputStream("myClientFiles/" + filename);
BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
You don't really need the BufferedOutputStream with this code, or at least with this code as it's going to be, but let it pass for now.
bytesRead = inputStream.read(byteArray, 0, byteArray.length);
currentTotalNumberOfBytes = bytesRead;
do { //read till the end and store total in bytesRead and add it to currentTotalNumberOfBytes
bytesRead = inputStream.read(byteArray, currentTotalNumberOfBytes, (byteArray.length - currentTotalNumberOfBytes));
if (bytesRead >= 0) {
currentTotalNumberOfBytes += bytesRead;
}
} while (bytesRead > -1); // when bytesRead == -1, there's no more data left and we exit the loop
bufferOutStream.write(byteArray, 0, currentTotalNumberOfBytes); //write the bytes to the file
To make this code shorter you might want to change it to the canonical form:
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
substituting variable names as appropriate. You will:
Save memory
Reduce latency
Have clear well-tested code that's been working for 18 years.
bufferOutStream.flush();
flush() before close() is redundant.
bufferOutStream.close();
socket.close();
Closing the socket after closing its output stream (or input stream) is redundant. Just close the output stream. In a finally block.

not able to send byte array from server to client,able to send from client to server

I have a task to do this.
Create a client and server socket interaction which accepts byte data and converts the byte data data received at server in the String and send back the response with the confirmation of the data conversation with success/unsuccess as the data passed will be with fix data length format so the validation should be done at server end.
As for e.g.
there are fields which ur sending to server like,
field 1 - number
field 2 - String
field 3 as Floating number i.e. 108.50
After conversion from byte to String :
152|any msg|108.50
In Byte it will be something like this,
10101|1001010010000000011000000000|1110111011
I have tried the following programs to do this
Server.java
public class Server extends Thread
{
private ServerSocket serverSocket;
public Server(int port) throws IOException
{
serverSocket = new ServerSocket(port);
//serverSocket.setSoTimeout(100000);
}
public void run()
{
while(true)
{
try
{
Socket server = serverSocket.accept();
byte Message[]=null;
DataInputStream in =
new DataInputStream(server.getInputStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
System.out.println("On this line"); //This doesnt get printed
buffer.flush();
data= buffer.toByteArray();
System.out.println(data);
String convertmsg = new String(data);
System.out.println("Msg converted "+convertmsg);
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
System.out.println("below dataoutputstream");
out.write("Success".getBytes());
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = 4003;
try
{
Thread t = new Server(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
client
public class Client {
public static void main(String args[]) throws IOException
{
int userinput =1;
while(userinput==1)
{
String serverName = "192.168.0.8";
int port = 4003;
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
System.out.println("above out.wirte()");
out.write("any msg".getBytes());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
System.out.println("converting array "+in);
byte[] data = IOUtils.toByteArray(in);
System.out.println(data);//This line doesnt get printed
//System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
System.out.println("Enter userinput ");
DataInputStream dis = new DataInputStream(System.in);
String s = dis.readLine();
userinput = Integer.parseInt(s);
}
}
}
If i send data from client to server in bytes,it reads it and prints it.Also then the line "Enter userinput " gets printed and if the user enters '1' the program continues.
But the problem is this program given above. If i try to send data from server stating "success"(meaning the data has been converted from bytes to String successfully) then the program stucks and the cursor doesnt go below the line which are in comments "This line doesnt get printed".There is no error printed and none of the program terminates.I am new to socket programming and dont understand much about networking.
Any help will be truly appreciated.
You're reading the input until end of stream, but the peer isn't closing the connection, so end of stream never arrives.
I suggest you read and write lines, or use writeUTF() and readUTF().

Strange behavior in TCP transmission

My server-client application consists of the following modules:
client (written in Java) connects to server and sends a file;
server (written in C) receives the file and sends a char array message.
The problem is that after receiving the file, the server is unable to send the message or the client is unable to receive it.
Here is my code for server application:
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s , new_socket;
struct sockaddr_in server , client;
int c, bytecount, nr_transf, rest_byte, i, bytesRead;
int recv_size, file_size;
char message[1000];
char buffer[1000];
int buffer_len = 1000;
FILE *f = fopen("out.jpg", "wb");
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
getch();
return 0;
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
//Bind
if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
getch();
return 0;
}
puts("Bind done");
//Listen to incoming connections
listen(s, 3);
//Accept and incoming connection
printf("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr*)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
getch();
return 0;
}
printf("Connection accepted");
//Receive image
while((bytesRead = recv(new_socket, buffer, buffer_len, 0)) > 0)
{
fwrite(buffer, 1, bytesRead, f);
}
fclose(f);
printf("\nReceive finished!");
//Send messsage
char my_message[100];
strcpy(my_message, "Hello World!");
send(new_socket, my_message, strlen(my_message), 0);
closesocket(s);
WSACleanup();
getch();
return 0;
}
And the code for client application:
public class MyClass
{
public static void main(String[] args)
{
String fileName = "1.jpg", receiveMessage;
File a_file = new File(fileName);
int j;
OutputStream output = null;
InputStream input = null;
ObjectInputStream in = null;
Socket socket = null;
try
{
// Create a socket
socket = new Socket("192.168.0.122", 8888);
FileInputStream fileInputStream = new FileInputStream(fileName);
byte[] buffer = new byte[1000];
int bytesRead = 0;
output = socket.getOutputStream();
input = socket.getInputStream();
while((bytesRead = fileInputStream.read(buffer))>0)
{
output.write(buffer,0,bytesRead);
}
fileInputStream.close();
System.out.println("Send finished!");
input.read(buffer);
System.out.println("Receive finished!");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
in.close();
output.close();
socket.close();
}
catch(Exception e)
{
}
}
}
}
Any ideas to solve this problem? Thanks in advance!
It's because you have blocking sockets. When a socket is created (by connecting or by accepting) it is in blocking mode. This means that if there is no data to receive it will not return, effectively blocking the caller.
So after you received the last byte in the loop in the server, the recv call will block indefinitely.
On Windows with winsockets, you use the ioctlsocket function to make a socket blocking or non-blocking. The linked reference have an example which shows hot to make a socket blocking or non-blocking.

Problems using single TCP/IP socket to send data from multiple concurrent threads

After browsing some other threads regarding my problem I think I've understood that I need to re-design my application. But just for clarification: I have a single TCP/IP connection between a client and a server. On the client side there are a number of threads running concurrently. Randomly one or more of these threads use the TCP/IP connection to communicate with the server. I've found out that, e. g. While a long running file transfer is active, using the connection with another thread concurrently might lead to errors. Though I've preceeded each message with a specific header including the data length it appears to me that the IP stack sometimes delivers a mix of more than one messages to my program, which means that though one message has net yet been delivered completely, part of another message is delivered to my read method. Is this a correct observation which matches the intended TCP/IP behaviour? Thanks in advance - Mario
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
For anybody who's interested: following is the source code of my test program. You may play with various values for the BUFFER_SIZE and the number of THREADS used to bombard the server socket with concurrent TCP/IP sends using the same socket. I've left out some error handling and removed a more sophisticated termination including the closing of the sockets. Test with a BUFFER_SIZE greater than 64KB always leads to errors on my machine.
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
public class TCPTest
{
private final static String INPUT_FILE = "c:/temp/tcptest.in";
private final static int BUFFER_SIZE = 64 * 1024 - 8; //65536;
private final static int MESSAGE_SIZE = 512 * 64 * 1024;
private final static int THREADS = 3;
private final static int SIZE_OF_INT = 4;
private final static int LENGTH_SIZE = SIZE_OF_INT;
private final static int ID_SIZE = SIZE_OF_INT;
private final static int HEADER_SIZE = LENGTH_SIZE + ID_SIZE;
private final static String NEW_LINE = System.getProperty("line.separator");
private ServerSocket m_serverSocket = null;
private Socket m_clientSocket = null;
private int m_iThreadCounter;
public static void main(String[] args)
{
new TCPTest();
} // main
public TCPTest()
{
final String id = "ReaderThread[*]";
// start a new thread creating a server socket waiting for connections
new Thread(new Runnable()
{
public void run()
{
try
{
// create server socket and accept client requests
m_serverSocket = new ServerSocket(12345);
m_clientSocket = m_serverSocket.accept();
// client request => prepare and read data
long startTime = System.currentTimeMillis();
byte[] buffer = new byte[BUFFER_SIZE];
ByteBuffer header = ByteBuffer.allocate(HEADER_SIZE);
int iTotalBytesRead = 0;
boolean fTerminate = false;
int iBytesRead;
// get hold of socket's input stream
InputStream clientInputStream = m_clientSocket.getInputStream();
// loop
while (false == fTerminate)
{
// loop to read next header
for (int i = 0; i < HEADER_SIZE; i++)
clientInputStream.read(header.array(), i, 1);
header.rewind();
// get information of interest
int iLength = header.getInt();
int iId = header.getInt();
int iLengthSoFar = 0;
int iBytesLeft = iLength;
int iBytesToRead;
// any length given?
if ((0 < iLength) && (BUFFER_SIZE >= iLength))
{
// that's the case => read complete message
while (iLengthSoFar < iLength)
{
// calculate number of bytes left
iBytesLeft = iLength - iLengthSoFar;
// calculate maximum number of bytes to read
if (iBytesLeft > BUFFER_SIZE)
iBytesToRead = BUFFER_SIZE;
else
iBytesToRead = iBytesLeft;
// read next portion of bytes
if ((iBytesRead = clientInputStream.read(buffer, 0, iBytesToRead)) != -1)
{
// maintain statistics
iTotalBytesRead += iBytesRead;
iLengthSoFar += iBytesRead;
} // if
else
{
// finish => print message
System.out.println("==> "+id+": ERROR length=<-1> received " +
"for id=<"+iId+">");
fTerminate = true;
break;
} // else
} // while
} // if
else
{
System.out.println("==> "+id+": ERROR data length <= 0 for id=<"+iId+">");
dump(header, 0, HEADER_SIZE / SIZE_OF_INT, "Error header");
} // else
} // while
System.out.println("==> "+id+": "+ iTotalBytesRead + " bytes read in "
+ (System.currentTimeMillis() - startTime) + " ms.");
} // try
catch (IOException e)
{
e.printStackTrace();
} // catch
} // run
}).start();
// create the socket writer threads
try
{
// ensure server is brought up and request a connection
Thread.sleep(1000);
System.out.println("==> "+id+": just awoke");
Socket socket = new Socket("localhost", 12345);
OutputStream socketOutputStream = socket.getOutputStream();
System.out.println("==> "+id+": socket obtained");
// create some writer threads
for (int i = 0; i < THREADS; i++)
// create a new socket writer and start the thread
(new SocketWriter(socket,
(i+1),
BUFFER_SIZE,
new String("WriterThread["+(i+1)+"]"),
socketOutputStream)).start();
} // try
catch (Exception e)
{
e.printStackTrace();
} // catch
} // TCPTestEx
private final static void dump(ByteBuffer bb, int iOffset, int iInts, String header)
{
System.out.println(header);
bb.rewind();
for (int i = 0; i < iInts; i++)
System.out.print(" " + Integer.toHexString(bb.getInt()).toUpperCase());
System.out.print(NEW_LINE);
} // dump
private class SocketWriter extends Thread
{
Socket m_socket;
int m_iId;
int m_iBufferSize;
String m_id;
OutputStream m_os;
protected SocketWriter(Socket socket, int iId, int iBufferSize, String id, OutputStream os)
{
m_socket = socket;
m_iId = iId;
m_iBufferSize = iBufferSize;
m_id = id;
m_os = os;
// increment thread counter
synchronized (m_serverSocket)
{
m_iThreadCounter++;
} // synchronized
} // SocketWriter
public final void run()
{
try
{
long startTime = System.currentTimeMillis();
ByteBuffer buffer = ByteBuffer.allocate(m_iBufferSize + HEADER_SIZE);
int iTotalBytesRead = 0;
int iNextMessageSize = 512 * m_iBufferSize;
int iBytesRead;
// open input stream for file to read and send
FileInputStream fileInputStream = new FileInputStream(INPUT_FILE);
System.out.println("==> "+m_id+": file input stream obtained");
// loop to read complete file
while (-1 != (iBytesRead = fileInputStream.read(buffer.array(), HEADER_SIZE, m_iBufferSize)))
{
// add length and id to buffer and write over TCP
buffer.putInt(0, iBytesRead);
buffer.putInt(LENGTH_SIZE, m_iId);
m_os.write(buffer.array(), 0, HEADER_SIZE + iBytesRead);
// maintain statistics and print message if so desired
iTotalBytesRead += iBytesRead;
if (iNextMessageSize <= iTotalBytesRead)
{
System.out.println("==> "+m_id+": <"+iTotalBytesRead+"> bytes processed");
iNextMessageSize += MESSAGE_SIZE;
} // if
} // while
// close my file input stream
fileInputStream.close();
System.out.println("==> "+m_id+": file input stream closed");
System.out.println("==> "+m_id+": <"+ iTotalBytesRead + "> bytes written in "
+ (System.currentTimeMillis() - startTime) + " ms.");
// decrement thread counter
synchronized (m_serverSocket)
{
m_iThreadCounter--;
// last thread?
if (0 >= m_iThreadCounter)
// that's the case => terminate
System.exit(0);
} // synchronized
} // try
catch (Exception e)
{
e.printStackTrace();
} // catch
} // run
} // SocketWriter
} // TCPTest
Yer. TCP is a byte oriented stream protocol. That means that the application receives an (undelimited) stream of bytes. The concept of "message" should be provided by the application (or use a message oriented protocol instead).

Categories