I'm trying to write an experimental server program that accepts a connection and sends a message to the client. I got the client to connect, but I can't seem to send the message without doing really odd things.
For example, in this snip, conn is a connected socket:
int sendRes;
char buf[1024];
strcpy_s(buf,"Testing!");
sendRes = send(conn,buf,strlen(buf),0);Well, when I connect to it via Telnet, it displays nothing and just quits. However, when I add the line cout << sendRes to the end of this snip, it suddenly works and displays Testing! on Telnet, just like it should.
And so, I would like to ask anyone who knows, why is it acting like so?
Could it be that the telnet client itself is waiting for an end of line marker to display the incoming buffer?
Try writing your own client and using recv to see if anything is incoming.
Then again, new line might not have anything to do with it since the cout is on the local side.
Try checking RFC854 for the full telnet specification (or, again, simply write your own client).
Related
I'm trying to use Boost Asio to make some code that talks to a remote system over UDP. The remote system in question is a bit of a pain in that once you connect to it once, if you close the connection (like you end your program) and then try to connect again, if it doesn't see the same port# used on my end of that connection it will refuse it.
I'm trying to figure out how I can specify the port that gets used on my side of the connection, but nothing I'm trying seems to work and I'm getting a bit frustrated. I have no control over the remote endpoint, so I really need to get this working on my end.
Here's the relevant code I'm using to try to make the connection and send my data over:
boost::asio::io_service io_context;
socket= new udp::socket(io_context);
remoteendpoint = boost::asio::ip::udp::endpoint(
ip::address::from_string(remoteipaddress_), 50200);
localendpoint = boost::asio::ip::udp::endpoint(
ip::address::from_string(localipaddress_), 50103);
socket->bind(localendpoint,ec);
socket->open(boost::asio::ip::udp::v4());
int sent = socket->send_to(boost::asio::buffer(buf, len),remoteendpoint, 0, ec);
When I go run my code, the remote side is reporting back that it's seeing the connection coming in from a different port# (on my side, which I'm trying to set to 50103) every time I run. I really need it to ALWAYS see it as 50103.
ie: How do I ensure that the socket is ALWAYS (every time I run my program):
LocalIP:50103 <------> RemoteIP:50200
Ideas??? I'm stumped...
Thanks!
Ok, I THINK I fixed it. Needed to do the bind() call AFTER the socket->open(). Remote side now consistently is reporting that my side is coming from port 50103 which is what I wanted.
Seems a bit weird that you have to open before binding, but ok.
I am creating a network client application that sends requests to a server using a QTcpSocket and expects responses in return. No higher protocol involved (HTTP, etc.), they just exchange somewhat simple custom strings.
In order to test, I have created a TCP server in Python that listens on a socket and logs the strings it receives and those it sends back.
I can send the first request OK and get the expected response. However, when I send the second request, it does not seem to get written to the network.
I have attached debug slots to the QTcpSocket's notification signals, such as bytesWritten(...), connected(), error(), stateChanged(...), etc. and I see the connection being established, the first request sent, the first response processed, the number of bytes written - it all adds up...
Only the second request never seems to get sent :-(
After attempting to send it, the socket sends an error(RemoteHostClosedError) signal followed by ClosingState and UnconnectedState state change signals.
Before I go any deeper into this, a couple of (probably really basic) questions:
do I need to "clear" the underlying socket in any way after reading ?
is it possible / probable that not reading all the data the server has sent me prevents me from writing ?
why does the server close the connection ? Does it always do that so quickly or could that be a sign that something is not right ? I tried setting LowDelay and KeepAlive socket options, but that didn't change anything. I've also checked the socket's state() and isValid() and they're good - although the latter also returns true when unconnected...
In an earlier version of the application, I closed and re-opened the connection before sending a request. This worked ok. I would prefer keeping the connection open though. Is that not a reasonable approach ? What is the 'canonical' way to to implement TCP network communication ? Just read/write or re-open every time ?
Does the way I read from the socket have any impact on how I can write to it ? Most sample code uses readAll(...) to get all available data; I read piece by piece as I need it and << to a QTextStream when writing...
Could this possibly be a bug in the Qt event loop ? I have observed that the output in the Qt Creator console created with QDebug() << ... almost always gets cut short, i.e. just stops. Sometimes some more output is printed when I shut down the application.
This is with the latest Qt 5.4.1 on Mac OS X 10.8, but the issue also occurs on Windows 7.
Update after the first answer and comments:
The test server is dead simple and was taken from the official Python SocketServer.TCPServer Example:
import SocketServer
class MyTCPHandler(SocketServer.StreamRequestHandler):
def handle(self):
request = self.rfile.readline().strip()
print "RX [%s]: %s" % (self.client_address[0], request)
response = self.processRequest(request)
print "TX [%s]: %s" % (self.client_address[0], response)
self.wfile.write(response)
def processRequest(self, message):
if message == 'request type 01':
return 'response type 01'
elif message == 'request type 02':
return 'response type 02'
if __name__ == "__main__":
server = SocketServer.TCPServer(('localhost', 12345), MyTCPHandler)
server.serve_forever()
The output I get is
RX [127.0.0.1]: request type 01
TX [127.0.0.1]: response type 01
Also, nothing happens when I re-send any message after this - which is not surprising as the socket was closed. Guess I'll have to figure out why it is closed...
Next update:
I've captured the network traffic using Wireshark and while all the network stuff doesn't really tell me a lot, I do see the first request and the response. Right after the client [ACK]nowledges the response, the server sends a Connection finish (FIN). I don't see the second request anywhere.
Last update:
I have posted a follow-up question at Python: SocketServer closes TCP connection unexpectedly.
Only the second request never seems to get sent :-(
I highly recommend running a program like WireShark and seeing what packets are actually getting sent and received across the network. (As it is, you can't know for sure whether the bug is on the client side or in the server, and that is the first thing you need to figure out)
do I need to "clear" the underlying socket in any way after reading ?
No.
is it possible / probable that not reading all the data the server has
sent me prevents me from writing ?
No.
why does the server close the connection ?
It's impossible to say without looking at the server's code.
Does it always do that so quickly or could that be a sign that
something is not right ?
Again, this would depend on how the server was written.
This worked ok. I would prefer keeping the connection open though. Is
that not a reasonable approach ?
Keeping the connection open is definitely a reasonable approach.
What is the 'canonical' way to to implement TCP network communication
? Just read/write or re-open every time ?
Neither was is canonical; it depends on what you are attempting to accomplish.
Does the way I read from the socket have any impact on how I can write
to it ?
No.
Could this possibly be a bug in the Qt event loop ?
That's extremely unlikely. The Qt code has been used for years by tens of thousands of programs, so any bug that serious would almost certainly have been found and fixed long ago. It's much more likely that either there is a bug in your client, or a bug in your server, or a mismatch between how you expect some API call to behave and how it actually behaves.
This question already has answers here:
Java socket API: How to tell if a connection has been closed?
(9 answers)
Closed 5 years ago.
When I'm using e.g. PuTTY and my connection gets lost (or when I do a manual ipconfig /release on Windows), it responds directly and notifies my connection was lost.
I want to create a Java program which monitors my Internet connection (to some reliable server), to log the date/times when my internet fails.
I tried use the Socket.isConnected() method but that will just forever return "true". How can I do this in Java?
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
Even though TCP/IP is "connection oriented" protocol, normally no data is sent over an idle connection. You can have a socket open for a year without a single bit sent over it by the IP stack. In order to notice that a connection is lost, you have to send some data on the application level.(*) You can try this out by unplugging the phone cable from your ADSL modem. All connections in your PC should stay up, unless the applications have some kind of application level keepalive mechanism.
So the only way to notice lost connection is to open TCP connection to some server and read some data from it. Maybe the most simple way could be to connect to some FTP server and fetch a small file - or directory listing - once in a while. I have never seen a generic server which was really meant to be used for this case, and owners of the FTP server may not like clients doing this.
(*) There is also a mechanism called TCP keepalive but in many OS's you have to activate it for all applications, and it is not really practical to use if you want to notice loss of connection quickly
If the client disconnects properly, a read() will return -1, readLine() returns null, readXXX() for any other X throws EOFException. The only reliable way to detect a lost TCP connection is to write to it. Eventually this will throw an IOException 'connection reset', but it takes at least two writes due to buffering.
Why not use the isReachable() method of the java.net.InetAddress class?
How this works is JVM implementation specific but:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
If you want to keep a connection open continually so you can see when that fails you could connect to server running the ECHO protocol yourself rather than having isReachable() do it for you and read and write data and wait for it to fail.
You might want to try looking at the socket timeout interval. With a short timeout (I believe the default is 'infinite timeout') then you might be able to trap an exception or something when the host becomes unreachable.
Okay so I finally got it working with
try
{
Socket s = new Socket("stackoverflow.com",80);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
Not as clean as I hoped but it's not working if I leave out the os.writeBytes().
You could ping a machine every number of seconds, and this would be pretty accurate. Be careful that you don't DOS it.
Another alternative would be run a small server on a remote machine and keep a connection to it.
Its probably simpler to connect to yahoo/google or somewhere like this.
URL yahoo = new URL("http://www.yahoo.com/");
URLConnection yc = yahoo.openConnection();
int dataLen = yc.getContentLength() ;
Neil
The isConnected()method inside Socket.java class is a little misleading. It does not tell you if the socket is currently connected to a remote host (like if it is unclosed). Instead, it tells you whether the socket has ever been connected to a remote host. If the socket was able to connect to the remote host at all, this method returns true, even after that socket has been closed. To tell if a socket is currently open, you need to check that isConnected() returns true and isClosed() returns false.
For example:
boolean connected = socket.isConnected() && !socket.isClosed();
I am currently writing a server backend for my iOS game. The server is written in C++ and compiled & run on a remove Ubuntu Server. I start the server through SSH using
sudo nohup ./mygameserver &
The server communications is written in TCP. The main function with the read-loop is written using standard C socket.h/netdb.h/in.h, and uses select() to accept many users on a nonblocking listening socket.
When I run the server in the foreground through SSH, everything seems to be working fine. It receives all packets I send in the right order, and with correct header info. When I use nohup and disconnect from SSH however... Everything seems to crash. A typical log from a user connect when the server software runs without SSH/in nohup mode looks like this:
CONNECTED TO SQL
Server starting...
Second thread initialized
Entering order loop
Got a new message of type: 0
Got a new message of type: 0
Got a new message of type: 0
Got a new message of type: 0
<this line continues ad infinitum>
I really have no idea why. I've made sure every print goes to nohup.out instead of std::cout, and the server sends an update to MySQL every 10 seconds to avoid timeouts.
Any ideas or input on what's wrong here? Let me know if you want some code samples, I just don't know which ones are interesting to this problem in particular. Thanks in advance.
I found out what was wrong.
In my server program I have a readSockets() function which is called after a call to select() in the main server loop. The readSockets() function responded to newline character pushed to stdin (for reasons I don't know) by nohup on startup, and as stdin is, in fact, also a FILE* connected to a file descriptor, my readSockets() function responded to stdin as a connecting client.
This obviously made the server crash, as stdin was never flushed (and was therefore read every time select() had returned). This again blocked the thread for other users.
I'm trying to make a MFC application(client) that connects to a server on ("localhost",port 1234), the server replies to the client and the client reads from the server's response.
The server is able to receive the data from the client and it sends the reply back to the socket from where it received it, but I am unable to read the reply from within the client.
I am making a CAsyncSocket to connect to the server and send data and a CAsyncSocket with overloaded methods onAccet and onReceive to read the reply from the server.
Please tell me what I'm doing wrong.
class ServerSocket:public CAsyncSocket{
public:
void OnAccept(int nErrorCode){
outputBox->SetWindowTextA("RECEIVED DATA");
CAsyncSocket::OnAccept(nErrorCode);
}
};
//in ApplicationDlg I have:
socket.Create();
socket.Connect("127.0.0.1",1234);
socket.Send(temp,strlen(temp)); //this should be sending the initial message
if(!serverSocket.Create()) //this should get the response i guess...
AfxMessageBox("Could not create server socket");
if(!serverSocket.Listen())
AfxMessageBox("Could not listen to socket");
You should be aware that all network operations are potentially time-consuming operations. Now, since you're using MFC's CAsyncSocket class, it performs all the operations asynchronously (doesn't block you). But return from the function doesn't mean it's already completed.
Let's look at the following lines of code:
socket.Connect("127.0.0.1",1234);
socket.Send(temp,strlen(temp)); //this should be sending the initial message
The first is the call to Connect, which most probably doesn't complete immediately.
Next, you call Send, but your socket isn't connected yet! It definitely returns you an error code, but since you don't bother checking its return value - you just happily wait to receive something.
So, the next rule for you, my friend, should be checking every return value for every function that you call, especially when it comes to networking where errors are legitimate and happen frequently.
You should only start sending after OnConnect has been called.
First, I don't see where you send the data to client (on server).
Second, Accept() does not mean data received. Accept means you have a new incoming connection, for which you need to create Another socket, to which data should be sent.