I am currently working on a file server in C.
When the client requests a file from the server, it writes to a socket. The server then writes back the data with a header on it. The client reads the header and then reads the actual data. When the client is being debugged, the server terminates the connection before the client has a chance to read the data.
To address this problem, I put in code to write a byte of 0 to the server when the client is done. The server, has a final read of the socket, looking for that byte but when the client is running under the debugger, it does not wait for the read on the server.
The socket is created with the following call on the server:
int socketId = socket(AF_INET, SOCK_STREAM, 0);
What should I do?
There are many challenges with writing client-server code. In this case you are also writing a protocol but may not realize it. Your protocol needs to be defined in a way that makes it clear what is expected from each side of the communication and the scenarios are non-trivial.
Here are some related questions:
(java) basic java socket programming problem
(c) Socket Programming Problem
(c) Socket Programming -- recv() is not receiving data correctly
What if the file contains a byte of 0?
You don't need this. Just close the socket. If the peer receives a clean close, it must have already received the entire file.
It sounds like you have no error checking in your unposted code.
We found the problem yesterday. The client was writing more bytes than the server was reading due to the fact that a variable was declared of the wrong type. Thanks for the responses.
Bob
Related
I am writing an application in C using socket programming. I wish to send the data from the server node to the client node. I use the read and write commands on the socket descriptor to get and send the data over the network respectively. Since, the underlying protocol used is TCP/IP, finally I receive the correct data. Is it possible to check on the client side that to receive the data correctly, how many packets were actually lost and re-transmitted? I am writing this application in Linux (debian) environment.
Any help is highly appreciated !
-Rahulkumar
/proc/net/tcp has a field retrnsmt, you simply need to find your socket in this list.
An alternative would be to use the TCP_INFO sockopt. The current layout of struct tcp_info can be found in linux/tcp.h. The field you want to use is probably tcpi_retrans.
I have a simple c program to copy an image from the server using TCP
The problem is it always fails to work with certain images, it only receives 'x' bytes and then times out.
The program is not the problem here since i have tried with different programs(C and python using bigger recv buffers) using TCP and they still fail at 'x'th bytes.
server: vxworks
client: linux
if i try connecting from SUN client using the same code, it has no problem receiving the image. I did a bit of packet sniffing and found that my client is requesting packet 'A' which has the 'x'th byte in it. The server sends it or re-transmits it, but the client never acknowledges it and timesout eventually.
Question is why is this image specific ? and only happens on linux client?
the file written to the client is always 'x' bytes long
It looks like network issue for me. What is the size of packet? Sounds strange but could not it be MTU blackhole between server and linux?
My friend once experienced this exact same problem and it turned out to that the payload of the binary image he was transferring was triggering a bug in a filtering router along way. The route would just drop the connection when a particular byte sequence passed through. Bizarre but true.
I have made a client and server application. In that when ever i am sending data to the server,the server is receiving data,but the server goes into the block state(waits to recv data still when data sending has been completed from client) then I compulsory needs to shutdown the socket form sending data. Which I don't want.
So can any one please tell me how to tell the server that my data transfer is completed.
My server behaves as following:
CLIENT: hi //now compulsory to shutdown the socket otherwise server
goes into block state
SERVER: hi //after this nothing can be
transferred since socket is closed
Where as i want like following:
CLIENT: hi
SERVER: hi
CLIENT: how are you?
SERVER: I am fine, thanks!
SERVER: What about you?
CLIENT: I am fine as well, thanks.
Other than setting the socket to be non-blocking, if that makes it easier, you need to develop your own protocol. This protocol would define the communications between client/server. For example, you could include data size, data, or just some form of data separator if you only use strings.
Look into the ioctlsocket function (on Windows) or the fcntl function (in linux), and in particular, set the socket to be non-blocking.
fcntl(sock_fd, F_SETFL, O_NONBLOCK);
Alternatively, have a separate thread to write to the socket while the first is blocking on the read.
Some more info here: http://rhoden.id.au/doc/sockets2.html
I am writing a C program where for every new request to be processed by server, I need to open a new TCP connection? That is every request from client needs to be handled by a separate TCP connection to a server listening on a particular port.
Can someone help me in code pointers?
How to maintain array of this socket identifiers (multiple sockets that needs to be opened)
How will I be able to read (Need to scroll through all open sockets and see if something interesting is to be read upon that socket)
Any code snippet will be highly useful?
You can use the select() function (assuming you are working with <sys/socket.h>), "gives you the power to monitor several sockets at the same time. It'll tell you which ones are ready for reading, which are ready for writing, and which sockets have raised exceptions" from http://beej.us/guide/bgnet/ (here you can download a pretty good book on network programming basics).
For a server example using select check http://beej.us/guide/bgnet/examples/selectserver.c
Hope it helps
If you need to save state with the socket, put it in a struct together with the data you need, and link the structures together as a list. For checking which sockets are ready see Maluchi's answer.
I have a small doubt in socket programming. i am able to send my data from client to server and my server processes the data. The o/p of the data processed, I want to send back to my client. So can we "write" the data back to the client using the same socket. I mean a server listens on a port before accepting connection and receiving data, so similarly, do i need to make my client listen to some other port (bind it some other socket) and make my server connect to that socket and transfer the data back. Any kind of example or explanation or references would be appreciated. Thanks a lot in advance.
Check out Beej's Network Programming Guide first of all.
The basic screenplay of a server/client connection goes like this:
Server listen()s on a fixed port, with a given socket.
Client connect()s to a the server port; client obtains a socket.
Server accept()s the connection, and accept() returns a new socket for the connection.
(Server continues listening on the original port with the original socket.)
For the specific connection with the client, the server write()s to the new socket it obtained when accept()ing the incoming connection. A busy server will have many, many sockets, but it will only ever need to bind() to one port. All connections come in to that one port, but the OS's networking protocol stack separates the data and makes it available at the connection-specific socket.
You don't need a new socket.
A socket is a duplex connection you can send data in both directions and you can even close the socket from one direction (don't want to write anymore) but still send data from the other direction.
Your socket is bi-directional, so there is no need to create another socket. Unless you are using some sort of middleware, such as Pub/Sub, there is no need to create another socket to enable bi-directional communication.
Technically it is right, the socket is duplex and you can send the data to the same socket you read from:
SOCKET s = socket()
... //Connect
int size = receive(s,...);
//make response
send(s, ...);
But in practice it depends on what are you going to do. It is possible to hang out socket if you have the following situation:
Process 1 sends very big data (<100K) over the socket by one send
operation
Process 2 receives data from 1 by portions and sends small packets to 1 (~20b). It is not a
confirmations, but some external events.
The situation goes into hangout, where the sending buffer of the 2 is full and it stops sending confirmations to 1.
2 and 1 are hanging in their send operations making a deadlock.
In this case I'd recommend using two sockets. One for read, one for write.
(Late answer, so mainly for anyone else who comes here looking for help)
I recently put up an example client/server application that closely follows Beej's Guide to Network Programming (which was also recommended by Kerrek SB in his answer). If you're looking for a simple working example of client/server communication, maybe this will help:
https://github.com/countvajhula/dummyclientserver
In particular, no, your client does not need to set up a separate listening socket to receive data from the server -- after the server has accepted the connection from the client, the server can simply send data back to the client on the same socket.