Really Simple Tcp Client

Really simple TCP client

Here is a simple TCP client that uses Sockets that I got working based on code in this tutorial (the code for the tutorial can also be found in this GitHub repository).

Note that this code is geared to sending strings back and forth between the client and server, usually in JSON format.

Here is the TCP client code:

import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClient {

public static final String TAG = TcpClient.class.getSimpleName();
public static final String SERVER_IP = "192.168.1.8"; //server IP address
public static final int SERVER_PORT = 1234;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;

/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TcpClient(OnMessageReceived listener) {
mMessageListener = listener;
}

/**
* Sends the message entered by client to the server
*
* @param message text entered by client
*/
public void sendMessage(final String message) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (mBufferOut != null) {
Log.d(TAG, "Sending: " + message);
mBufferOut.println(message);
mBufferOut.flush();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}

/**
* Close the connection and release the members
*/
public void stopClient() {

mRun = false;

if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}

mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}

public void run() {

mRun = true;

try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

Log.d("TCP Client", "C: Connecting...");

//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);

try {

//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

//receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));

//in this while the client listens for the messages sent by the server
while (mRun) {

mServerMessage = mBufferIn.readLine();

if (mServerMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}

}

Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}

} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}

}

//Declare the interface. The method messageReceived(String message) will must be implemented in the Activity
//class at on AsyncTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}

}

Then, declare a TcpClient as a member variable in your Activity:

public class MainActivity extends Activity {

TcpClient mTcpClient;

//............

Then, use an AsyncTask for connecting to your server and receiving responses on the UI thread (Note that messages received from the server are handled in the onProgressUpdate() method override in the AsyncTask):

public class ConnectTask extends AsyncTask<String, String, TcpClient> {

@Override
protected TcpClient doInBackground(String... message) {

//we create a TCPClient object
mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
@Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();

return null;
}

@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//response received from server
Log.d("test", "response " + values[0]);
//process server response here....

}

To start the connection to your server, execute the AsyncTask:

new ConnectTask().execute("");

Then, sending a message to the server:

//sends the message to the server
if (mTcpClient != null) {
mTcpClient.sendMessage("testing");
}

You can close the connection to the server at any time:

if (mTcpClient != null) {
mTcpClient.stopClient();
}

Simple TCP Client

With Ørjan Johansen's help I figured it out. forkFinally was creating a thread then after that main thread was getting closed. That line was meant to wait until talk finished and then close the connection. It had to be (also shortened it)

main :: IO ()
main = withSocketsDo $ do
handle <- connectTo "192.168.137.1" (PortNumber 44444)
talk handle `finally` hClose handle

talk :: Handle -> IO ()
talk handle = do
hSetNewlineMode handle universalNewlineMode
hSetBuffering handle LineBuffering
_ <- race fromServer toServer
return ()
where
fromServer = forever $ do
line <- hGetLine handle
print line
toServer = do
line <- getLine
case line of
-- server accepts /quit as disconnect command so better send it to the server
":quit" -> do hPutStrLn handle "/quit"; return "Quit"
_ -> do hPutStrLn handle line; toServer

I hope this code is safe :D

Simple java TCP client

You are trying to create a new Socket connection on same port in sentThread. First connection is created in ClientThread class and when you are pressing sent button you are creating another Socket connection on same port 502. I think that's is the main problem.

Try to use existing Socket connection in sentThread class.

class sentMessage implements Runnable
{
@Override
public void run()
{
try
{

//InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
//serverAddr.getByName(serverIpAddress);
// socket = new Socket(serverAddr, 502);

// os = new DataOutputStream(socket.getOutputStream());
str = smessage.getText().toString();
str = str + "\n";
msg = msg + "Client : " + str;
handler.post(new Runnable()
{
@Override
public void run()
{
chat.setText(msg);
}
});
os.writeBytes(str);
os.flush();
//os.close();
}
catch(IOException e)
{
}
}
}

Edit:
You you want to send multiple message then don't close DataOutputStream. Remove os.close(); and os = new DataOutputStream(socket.getOutputStream()); line from sentMessage class.
Initialize your os when you are connecting first time. Then every time you want to send message use that os instance.

In ClientThread class initialize os after connection created

   socket = new Socket(serverAddr, 502);
os = new DataOutputStream(socket.getOutputStream());

Simple tcp client examples in emacs elisp?

I was looking for something a lot simpler. I've finally managed to code it from a stripped down TcpClient example. This works from the command line if you save it as client.el, do chmod +x client.el, and ./client.el. It will print out what ever the server decides to send and quit after 300 seconds. It really needs some comments to explain what it going on.

#!/usr/bin/emacs --script

(defvar listen-port 9999
"port of the server")

(defvar listen-host "127.0.0.1"
"host of the server")

(defun listen-start nil
"starts an emacs tcp client listener"
(interactive)
(make-network-process :name "listen" :buffer "*listen*" :family 'ipv4 :host listen-host :service listen-port :sentinel 'listen-sentinel :filter 'listen-filter))

(defun listen-stop nil
"stop an emacs tcp listener"
(interactive)
(delete-process "listen"))

(defun listen-filter (proc string)
(message string))

(defun listen-sentinel (proc msg)
(when (string= msg "connection broken by remote peer\n")
(message (format "client %s has quit" proc))))

(listen-start)
(sleep-for 300)
(listen-stop)

Android-how to implement TCP-ip client inside intentservice

well the solution was easy
i just convert my tcp object to static

old

private TCPClient mTcpClient;

new

private static TCPClient mTcpClient;

and really i dont understand why it's work as static, i will be thankful if someone can explain this

Checking a TcpClient is actually connected

TCP doesn't really work they way you seem to think it does, although there are some things we can do to make it work better for you. But first let's understand a little better how it works and why you see the behavior you do.

When you open a TCP connection, TCP uses a 3-way handshake to set up the connection. The client sends a SYN, the server responds with SYN+ACK, and then the client sends back an ACK. If neither side tries to send anything the connection will just sit there idle. You can unplug the cable from your machine. A tree can fall and take out your internet service. The internet provider can come repair your internet service, and you can plug the cable back into the ethernet port. And then the client can write to the socket and it should be delivered to the server. (Firewalls unfortunately deliberately break standards, and your firewall may have decided to time out the connection while you were waiting for your ISP to fix your service.) However, if you tried to make another connection while the cable was unplugged, TCP would try to send a SYN, and most likely discover that there is "no route to host." So it can't set up a new connection.

If you had tried to write to the socket while your internet service was out, TCP would try to send the data and wait for an ACK from the server. After a retransmission timeout, if it hasn't received an ACK, it will try again and exponentially back off on the timeout. After typically 15 tries it will give up, which would typically take anywhere between half an hour to an hour and a half.

As you can see, TCP is trying to be resilient in the face of failure, whereas you want to learn about failures very quickly. Systems that need to react quickly to connection failure (such as electronic stock exchanges which typically cancel open orders on connection failure) handle this as part of a higher level protocol by sending heartbeat messages periodically and taking action when a heartbeat is sufficiently overdue.

But if you can't control the protocol, there are some socket options you can use to improve the situation. SO_KEEPALIVE causes TCP to periodically send keepalive packets and it will eventually time out depending on the settings of TCP_KEEPIDLE, TCP_KEEPINTVL, and TCP_KEEPCNT. TCP_USER_TIMEOUT allows you to set a timeout for how long data written to a socket can remain unacknowledged.

How exactly these two options work and interact are implementation dependent, and you have to consider what is going to happen when there is no unacknowledged data, when there is unacknowledged data, and when there is a slow consumer resulting in a zero window. In general it is advisable to use them together with TCP_USER_TIMEOUT set to (TCP_KEEPIDLE + TCP_KEEPINTVL*TCP_KEEPCNT) * 1000 to get a consistent result.

Our friends a Cloudflair have a nice Blog entry about how exactly these work together, but on Linux, unfortunately. I'm not aware of anything as comprehensive as this for Windows.



Related Topics



Leave a reply



Submit