the program using socket to communicat has stuck - c

I used socket in my program to let the client communicate with the prover namely the server. Firstly, the client send local file to the prover, and it succeed. Then, the client send signatures of that file to the prover, but the program has stuck. I think the recv function of the prover cannot receiver any data so it failed, but I don't know why it happend. Can anyone explain it?
/* send file */
if (on_cmd_send_file_client(sockProver, username, party, filename, blocksize, blocknum)) {
printf("%s(%d)-%s:%d-%s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
return (errno ? errno : -1);
}
/* send signature */
length = pairing_length_in_bytes_G1(pairing);
if (on_cmd_send_sig_client(sockProver, username, party, filename, length, blocknum)) {
printf("%s(%d)-%s:%d-%s\n", __FILE__, __LINE__, __FUNCTION__, errno, strerror(errno));
return (errno ? errno : -1);
}

I suggest you start both the client and a server in debugging mode to understand what exactly is happening. As it stands now, it is difficult to say what exactly is the cause of the communication stall. There might be a framing problem, i.e., the server waits for more data, while the client thinks it already sent everything. I saw quite many cases in which recv was assumed to do framing, which it does not for TCP.

Related

C : String comparing

bool done;
done = false;
while (!done) {
/* read the message */
bzero(msg, 100);
printf("[client]Type something: ");
fflush(stdout);
read(0, msg, 100);
if (strcmp(msg, "/done") == 0) {
done = true;
/* sending the message to the server */
if (write(sd, msg, 100) <= 0) {
perror("[client]Error sending the message to the server.\n");
return errno;
}
} else {
/* sending the message to the server */
if (write(sd, msg, 100) <= 0) {
perror("[client]Error sending the message to the server.\n");
return errno;
/* reading the answer given by the server*/
if (read(sd, msg, 100) < 0) {
perror("[client]read() error from server.\n");
return errno;
}
/* printing the received message */
printf("[client]The received message is: %s\n", msg);
}
}
Here's the code that i have problem with. So i want to send messages to the server until I send the message "/done", the code works, I send messages continuously but even when i type and send "/done" the process doesn't end.
I think there's a problem with the bzero function that "clears" the msg or maybe i don't understand it so good.
I also tried to wrote my own function to check if two strings are the same, but no effect also.
So how should i write the condition or "clear" the msg so i can send messages continuously and after i send "/done" the execution ends?
P.S. the msg is declared earlier in the code as char msg[100];
When you read from 0, you're reading from stdin. If that is a terminal that you are typing into (you don't say), you likely have it set up in normal (canonical) mode, so you'll read a line, which probably includes a newline (\n) character. So when you enter /done, the string you get in your msg buffer is "/done\n" which doesn't match "/done"...
read(2) is including the '\n' at the end of the string. When you use low-level read you get everything. When trying to debug strings, it can be helpful to put quotes in your print statement, like
printf("[client]The received message is: '%s'\n", msg);
as this immediately shows invisible whitespace.
TCP is not a message protocol. It does not glue bytes together into messages. If you want to use TCP to send and receive messages, you'll need to implement functions that send and receive messages.
I must strongly caution you not to fail into the trap of thinking that changing your code from happening not to work when you tried it to happening to work when you try it means that you've fixed it. Your code fails if read returns 1. You need to implement a sensible function to receive a message or your code will only be working by luck, and I can tell you from painful experience that one day your luck will run out.

Can it realistically happen that for an UDP socket, the send function doesn't fail, but still writes less data than requested?

From man 2 sendto:
On success, these calls return the number of bytes sent. On error, -1 is returned, and errno is set appropriately.
Am I to understand that failure to write all data is not treated as a failure of these functions, therefore it realistically may happen that when writing to an UDP socket, the send() function writes less data than requested, but the reason of this failure is not specified in errno?
Or can I presume that send() will either return -1 and set errno appropriately, or return the number of bytes requested to send?
In other words: Is this error handling code sufficient:
if(send(udp_sock_fd, buf, buflen, 0) == -1) {
int err = errno;
fprintf(stderr, "Send failed:\n");
fprintf(stderr, strerror(err));
}
Or is it rather necessary to write something like that:
ssize_t bytes_send = send(udp_sock_fd, buf, buflen, 0);
if(bytes_send == -1) {
int err = errno;
fprintf(stderr, "Send failed:\n");
fprintf(stderr, strerror(err));
} else if(bytes_send < buflen) {
fprintf(stderr, "Incomplete send for unknown reason.\n");
}
There is no concept of sending just part of a datagram. It either all goes, or none of it goes. The OS or network drivers will not split the datagram for you. Returning the character count sent must just be a courtesy, to fall inline with other send API functions.
Also from the man page:
For sendto(), if the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.
Obviously, #Paul Bentley has already provided the correct answer, but in case you're worried that -- even though this is never supposed to happen -- there might be some rare error condition where it does, it may be helpful to note that at least for a particular implementation (Linux), the code for udp_sendmsg in net/ipv4/udp.c (which is what's ultimately called for a send on a UDP socket) has only one exit that can return a non-negative value, and it returns the length supplied by the caller:
int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
... code that doesn't modify len ...
out:
...
if (!err)
return len;
...
}

Multiple calls to send() are merged into one call to recv()

I have a client-server application.
The client is sending a string followed by an integer using two distinct send() calls. These two data are supposed to be stored into two different variables on the server.
The problem is that both variables sent are received on recv() call. Therefore, the two strings sent by the two distinct send()s are chained and stored in the buffer of the first recv().
server.c:
printf("Incoming connection from client %s:%i accepted\n",inet_ntoa(clientSocketAddress.sin_addr),ntohs(clientSocketAddress.sin_port));
memset(buffer,0,sizeof(buffer));
int sizeofMessage;
if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0)==sizeofMessage)<0)
{
printf("recv failed.");
closesocket(serverSocket);
clearWinsock();
return EXIT_FAILURE;
}
char* Name=buffer;
printf("Name: %s\n",Name);
if ((recv(clientSocket,buffer,MAXBUFFERSIZE,0))<0)
{
printf("bind failed.");
closesocket(serverSocket);
clearWinsock();
return EXIT_FAILURE;
}
int integer=ntohs(atoi(buffer));
printf("integer: %i\n",intero);
client.c:
if (send(clientSocket,Name,strlen(Name),0)!=strlen(Name))
{
printf("send failed");
closesocket(clientSocket);
clearWinsock();
return EXIT_FAILURE;
}
printf("client send: %s",Name);
int age=35;
itoa(htons(age),buffer,10);
sizeofBuffer=strlen(buffer);
if (send(clientSocket,buffer,sizeofBuffer,0)!=sizeofBuffer)
{
printf("bind failed.");
closesocket(clientSocket);
clearWinsock();
return EXIT_FAILURE;
}
How can I fix it? What am I doing wrong?
TCP is a streaming protocol. It is not aware at all of any kind of "message" boundaries. It does not add such information dependend on single calls to send().
Due to those facts any number of send()s on the sender side can lead to any number of recv()s (up to the number of bytes sent) on the receiver side.
To get around this behaviour define and implement an application level protocol to distinguish the different "messages" that had been sent.
One cannot rely on recv()/send() receiving/sending as much bytes as those two functions were told to receive/send. It is an essential necessity to check their return value to learn how much bytes those functions actually received/sent and loop around them until all data that was intended to be received/sent had been received/sent.
For examples how this "looping" could be done
for writing you might like to have look at this answer: https://stackoverflow.com/a/24260280/694576 and
for reading on this answer: https://stackoverflow.com/a/20149925/694576
This is how TCP works. Treat it as a byte stream.
Put some basic protocol on top of it - delimit you application messages with some known byte value, or prepend your messages with length field.
Or switch to UDP, which gives you datagram semantics you are looking for, if you can tolerate/recover from occasional packet loss.
You can add a short time interval like sleep(5) between two messages, if time does not matter too much in your application.

Permission denied when trying to write into log file

I have a problem writing into a log file in my C/C++ prog.
Here's an example of the code where the problem occurs
EnterCriticalSection(&critical);
printf("\nWaiting for a connection on TCP port %d (nbr of current threads = %d)...\n", pServer->TCPServerPort, (*pServer->lChildInfo));
AddLog("Waiting for a connection on TCP port %d (nbr of current threads = %d)...", pServer->TCPServerPort, (*pServer->lChildInfo));
LeaveCriticalSection(&critical);
// creating variables to be passed to the thread
struct*ThreadData = (struct*) malloc(sizeof(struct));
ThreadData->csock = (int*)malloc(sizeof(int));
memcpy(&ThreadData->pServer,&pServer,sizeof(pServer));
if((*ThreadData->csock = accept( pServer->ListenSocket, (SOCKADDR*)&sadr, &addr_size))!= INVALID_SOCKET ){
ThreadData->dwIP = sadr.sin_addr.s_addr;
ThreadData->wPort = sadr.sin_port;
printf("Received connection from %s:%d \n",inet_ntoa(sadr.sin_addr), ntohs(sadr.sin_port));
AddLog("Received connection from %s:%d ",inet_ntoa(sadr.sin_addr), ntohs(sadr.sin_port));
AddLog is the function i wrote in order to write into the file :
FILE *fichier = NULL;
va_list ap;
va_start(ap, log);
//fichier = fopen("log.log","a");
fichier = _fsopen("log.log", "a", SH_DENYNO);
if (fichier == NULL)
printf("Error log: %d (%s)\n", errno, strerror(errno));
else {
fprintf(fichier,":");
vfprintf(fichier, log, ap);
fprintf(fichier,"\n");
va_end(ap);
fclose(fichier);
}
What I can't really explain is that the first AddLog ("Waiting for...." and all the ones before..) are correctly written into the file. But when i try a connection, the logs coming then (received connection from...) are not written into the file and i always get the error 13 "Permission denied".
I used chmod 777 into the file, i also tried _fsopen function and i still get this error once i enter into the thread.
If someone have any idea it would be reaaally helpful.
Thanks to all
I don't know exactly if it the problem , But i would suggest using "a+" inside _fsopen
for shared append because thread another process.
I don't know if it is still relevant , but I have to suggest you to use a bit better solution:
(I encountered the same problem few days ago and the solution was more than trivial)
I just implemented a shared queue and all the logs I added in to the queue afterwards I run a worker thread that was checking the queue and was writing to the file if the queue wasn't empty.
I hope it helped have a nice day :)

Sending structs with ZeroMQ and ProtocolBuffers

I'm writing a program that's supposed to send C structures via ZeroMQ.
Therefore I'm using Google's ProtocolBuffers to serialize the structs.
I do now have the problem that my subscriber side is not receiving anything.
The Publisher prints out "Message successfully sent" so I think the Error occurs on the Subscribers side.
Publisher:
int main (void)
{
Message protomsg = MESSAGE__INIT;
void *buf;
unsigned len;
void *context = zmq_ctx_new();
void *subscriber = zmq_socket(context, ZMQ_PUB);
zmq_bind(subscriber, "ipc://my.sock");
//Initialising protomsg (not so important)
//sending message
len = message__get_packed_size(&protomsg);
buf = malloc(len);
message__pack(&protomsg, buf);
zmq_msg_t output;
zmq_msg_init_size(&output, len);
zmq_msg_init_data(&output, buf, len, NULL, NULL);
if(zmq_msg_send(&output, subscriber, 0) == -1)
perror("Error sending message \n");
else
printf("Message successfully sent \n");
zmq_msg_close(&output);
free(buf);
zmq_close (subscriber);
zmq_ctx_destroy (context);
return 0;
}
Subscriber:
int main (void){
Message *protomsg;
void *context = zmq_ctx_new ();
void *publisher = zmq_socket (context, ZMQ_SUB);
zmq_connect(publisher, "ipc://my.sock");
zmq_setsockopt(publisher, ZMQ_SUBSCRIBE, "", 0);
// Read packed message from ZMQ.
zmq_msg_t msg;
zmq_msg_init(&msg);
if(zmq_msg_recv(&msg, publisher, 0) == -1)
perror("Error receiving message \n");
else
printf("Message received");
memcpy((void *)protomsg, zmq_msg_data(&msg), zmq_msg_size(&msg));
// Unpack the message using protobuf-c.
protomsg = message__unpack(NULL, zmq_msg_size(&msg), (void *)&data);
if (protomsg == NULL)
{
fprintf(stderr, "error unpacking incoming message\n");
exit(1);
}
printf("Address: %u, Type: %u, Information[0]: %u, Information[1]: %u \n", protomsg->address-48, protomsg->frametype, protomsg->information[0], protomsg->information[1]);
zmq_msg_close (&msg);
// Free the unpacked message
message__free_unpacked(protomsg, NULL);
//close context,socket..
}
Don't know if anyone still cares about this, but here goes... I agree with #Steve-o that this is a timing issue, although I think the problem is that you are closing the publisher socket too soon.
Your publisher code publishes the message then immediately closes the socket and terminates the context. So the message exists in the publisher for milliseconds and then is gone forever.
If you run the publisher first, it does it's thing, exits and the message is gone. When you start the subscriber it attempts to connect to an IPC socket that is no longer there. ZeroMQ allows this and the subscriber will block until there is an IPC socket to connect to.
I have not reviewed the ZeroMQ IPC source code, but I suspect that, under the covers, subscriber is periodically attempting to connect to the publisher socket. Now if you run the publisher again, it might work but you have a serious race condition. If you start the publisher at the exact instant the ZeroMQ worker was attempting to retry, the connect might happen and you might even get your message before the publisher destroys everything.
I am pretty sure the problem has nothing to do with structs and protobuf. From the ZeroMQ point of view you are just sending bytes. There is no difference. If your test cases for ZeroMQ strings were truly identical with the test cases for ZeroMQ structs - then perhaps the code change added or removed a few nano-seconds that was able to break the race condition the wrong way.
Specific suggestions:
rename the socket in publisher to be "publisher" instead of subscriber (copy/paste error)
add a sleep for 30 seconds just before zmq_close (publisher);
hopefully this will fix the problem for your test code
if this does not fix it, consider switching to tcp transport and use wireshark to diagnose what is really going on.

Resources