scanf() not working after ENTER - c

I'm making this simple example from server to client where the server functions as a echo server! So the client gets input from the user and sends it to the server, the server then sends it back.
I just got stuck on the input from the user. I used stuff like getchar, scanf and fgets. But when I start typing and press ENTER, then it should continue to the next thing in the program... Sadly that ain't happening.
Here is my code for the message part:
while(1)
{
char message[1000], servermessage[1000];
printf("You: ");
scanf("%s", message);
printf("%s\n", message);
if (send(sock, message, strlen(message), 0) < 0)
{
printf("sending failed\n");
return (EXIT_FAILURE);
}
int received = recv(sock, servermessage, sizeof(servermessage), 0);
if (received < 0)
{
printf("received failed\n");
return (EXIT_FAILURE);
}
servermessage[received] = '\0';
printf("Server: %s\n", servermessage);
}
close(sock);

After you type the first time, you call recv(), it will block until there is some data to read, you client didn't read any data, so nothing happen. You need check your echo server to find what's wrong. If you need a echo server to test your client, you can use the code for server here.

Related

C sockets: why is my server appending extra characters in the end?

I am writing a simple server/client socket in C. The client asks the user to input a message and the server responds by repeating the same. The problem is when I send a message from the client the server responds back by appending extra character. How do I fix this.
This is my Client code
while(1) {
bzero(buffer, BUFSIZE);
printf("Enter Message: ");
scanf("%s", buffer);
//send some data
if(send(socket_fd, buffer, strlen(buffer), 0) <0) {
fprintf(stderr,"sending failed\n");
return 1;
}
//receive a reply from the server
if(recv(socket_fd, server_reply, BUFSIZE,0)<0)
{
fprintf(stderr,"failed to reply. \n");
break;
}
fprintf(stdout, "Reply: %s\n ", servreply);
}
This is my server code
int read_size;
while((read_size = recv(client_socket_fd, buffer, BUFSIZE,0))>0)
{
// Reply back to the client
if (0 > write(client_socket_fd, buffer, strlen(buffer))) {
fprintf(stderr, "could not write back to socket\n");
} else {
fprintf(stdout, "message back to client\n");
}
}
if(read_size==0)
{
fprintf(stderr,"disconnected.\n");
fflush(stdout);
}
else if(read_size==-1){
fprintf(stderr, "error.\n");
}
This is the output
Enter Message: welcome
Reply: welcome
Enter Message: hello
Reply: hellome
Enter Message: hi
Reply: hillome
You need a string in order to use strlen(). Your arrays are not strings, rely on read_size instead for the length of the buffer.
Strings in c are just a sequence of printable characters followed by a '\0', and none of your arrays has any '\0' so strlen() is causing undefined behavior. The strlen() function actually scans the string until it finds the '\0' and in the process it counts how many characters were there.
#Iharob's answer is correct. Basically, change the line:
write(client_socket_fd, buffer, strlen(buffer))
to:
write(client_socket_fd, buffer, read_size)
It isn't. You are printing junk at the end of your buffer. You're also ignoring end of stream.
if(recv(socket_fd, server_reply, BUFSIZE,0)<0) {
fprintf(stderr,"failed to reply. \n");
break;
}
fprintf(stdout, "Reply: %s\n ", servreply);
should be
int count;
if((count = recv(socket_fd, server_reply, BUFSIZE,0))<0) {
fprintf(stderr,"failed to reply. \n");
break;
}
else if (count == 0) {
// EOS
fprintf(stderr, "peer has disconnected.\n");
break;
} else {
fprintf(stdout, "Reply: %.*s\n ", count, servreply);
}
Your 'write back to the client' is also incorrect:
if (0 > write(client_socket_fd, buffer, strlen(buffer))) {
should be
if (0 > write(client_socket_fd, buffer, read_size)) {

Server program not ending when "quit" string entered

I've got a basic linux socket program mostly running that accepts strings from the client to send to the server. When "quit" is typed, my client program ends, but the server one prints out "quit" endlessly until you kill the program. Either I'm not reading the string properly or my logic is off.
Code section...
while (1)
{
//fetch message from client and write to stdout
num_client_bytes = recv(client_sockfd, buf, LEN, 0);
if (-1 == num_client_bytes)
{
perror("server-- recv failed");
}
else
{
printf("client msg: %s", buf);
if (0 == strcmp(buf, "quit\n"))
{
break;
}
}
}
//remove local socket file and close sockets
unlink(SOCKET_NAME);
close(client_sockfd);
close(server_sockfd);
return 0;
You need to memset buf prior to recv
recv will not add '\0' at the end of string read from socket,
also you should check if recv read entire 4 bytes, then change:
strcmp(buf, "quit\n")
to
strncmp(buf, "quit\n",4)// if you are not sure client sends \n

Trouble reading data from client to server

I am having trouble reading values from a client from my server/client program. User are supposed to enter a country in the client and the server are supposed to process the value and then return the information (capital, currency) related to the country.
For my program, the server is able to return the correct data for the first time. For example, user key in China, the server will return the capital as beijing etc..
However, when the user entered for example 'Germany' for the second time, the server does not return any data at all.
Hope you guys can identify the error in my codes. Thanks in advance!
Thanks in advance!
On client side, after printing received answer you're closing clientFd and not trying to reconnect for further use. In fact for second time write is doing on a closed file descriptor. One solution is this:
while (1) {
/* Create a socket, bidirectional, default protocol */
clientFd = socket(AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);
do { /* Loop until a connection is made with the server */
result = connect(clientFd, serverSockAddrPtr, serverLen);
printf("Attempting to connect...\n");
if (result == -1) sleep(1); /* Wait and then try again */
} while (result == -1);
char country[300];
printf("%s \n", " ");
printf("Please enter country > ");
fflush(stdout);
fgets(country, sizeof(country), stdin);
printf("%s \n", " ");
if (0 == strcmp(country, "end\n")) {
printf("Thank you for using country services\n");
exit(0);
} else {
write(clientFd, country, strlen(country));
parse(clientFd);
}
close(clientFd);
printf("%d\n", clientFd);
clientFd = 0;
}

How to use recv to recieve long text strings

I am trying to create a server and client program that sends a string from client to server where the server executes that string and sends the output back to the client. I am doing this in linux and I am very confused why my program isnt working the least bit. Here is the code.
**Client**
int main()
{
//Code to use unix socket here
if (connect(s, (struct sockaddr *)&remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
while(printf("> "), fgets(str, MAX, stdin), !feof(stdin)) {
if (send(s, str, strlen(str), 0) == -1) {
perror("send");
exit(1);
}
}
done=0;
do {
if(t=recv(s, str, MAX, 0)<0)
perror("recv failed at client side!\n");
str[t] = '\0';
if(strcmp(str, "ENDOFTRANS")==0)
{
printf("\nRead ENDOFTRANS. Breaking loop.\n");
done=1;
}
printf("Server > %s", str);
} while(!done);
}
And then the server code is:
**Server**
#define MAX 1000
int main(void)
{
//Unix socket code
//This process is now a daemon.
daemon();
//Listens for client connections, up to 5 clients can queue up at the same time.
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
for(;;) {
int done, n, status;
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((newsock= accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
printf("Connected.\n");
done = 0;
do {
switch(fork())
{
case -1: //ERROR
perror("Could not fork.\n");
break;
case 0: //CHILD
//Accept string from client.
//Edit: Why am I getting an error here? says: Invalid argument.
if(n = recv(newsock, str, MAX, 0)) {
perror("Recv error at server side.\n");
exit(1);
}
str[n]='\0';
if (n <= 0) {
if (n < 0)
perror("recv");
done = 1;
}
printf("String=>%s<",str);
//Redirect socket to STDOUT & STDERR.
test = close(WRITE); assert(test==0);
test = dup(newsock); assert(test==WRITE);
test = close(ERROR); assert(test==0);
test = dup(newsock); assert(test==ERROR);
if (!done)
{
if (str==something)
{
//execute command
}
else {
//Fork and execvp the command
}
//Sends End of Transaction character.
ENDTHETRANS();
exit(0);
}
break;
default: //PARENT
//Parent keeps accepting further clients.
wait(&status);
if ((newsock= accept(s, (struct sockaddr *)&remote, &t)) == -1) {
perror("accept");
exit(1);
}
printf("Connected.\n");
done=1;
break;
}
} while (!done);
}
close(s);
}
Im relatively new to programming in general and from my understanding the client code is good except that when it recieves the text back from the server it only recieves the text in small bits (2 rows at a time). I have to keep pressing enter on client promt to get the rest of the input. I have tried so many things that by this point I dont even know what I am doing wrong anymore.
Firstly, in the server code, after it recieves the string from the client I have a printf("String=>%s<",str); that outputs the string. However when the server prints the output as String=>ls -l the < key at the end gets eaten up somehow. It shouldnt be doing that right?
Any help much appreciated. Please bare in mind that I am a beginner and have only used pipes as inter process communcation before. Now I wanna make my first unix socket program.
Thanks in advance.
The usual problem in cases such as this is not realizing that SOCK_STREAM sockets don't preserve message boundaries. So data sent with a send call might be split up and received in multiple recvs, or it might be coalesced and multiple sends end up in a single recv. Most importantly, when a kernel send buffer fills up, a send call might write partial data (sending only some of the requested data) and return a short return value. You need to test for this and resend the rest of the data.
Another problem that often shows up is issues with line endings (particularly when talking between linux and windows). There may be extra carriage return characters (\r) in the either the client or server that confuse the other side. These tend to result in apparently missing or truncated output when printed.
edit
The line
if(t=recv(s, str, MAX, 0)<0)
is equivalent to
if(t = (recv(s, str, MAX, 0)<0))
that is, it sets t to 0 or 1 depending on whether there was an error or not. As with most errors of this type, turning on warnings will give you some indication about it.

C programming socket buffer

Re: this client<->server (foodrequest-foodinfo scenario) I am trying to send receive to a successful client-server connection sock_fd. In this loop, I receive the first information back but the next iteration stops at the keyboard input ie readInFood(). Is there anything wrong with the way I am handling the buffer? or otherwise.
RESPONSE_BUFFER = 2200;
INPUT_BUFFER = 100;
int numbytes;
char foodType[INPUT_BUFFER];
char foodResponse[RESPONSE_BUFFER];
do {
//send a message to server
if (send(sock_fd, readInFood(foodType), INPUT_BUFFER, 0) == -1)
perror("send");
//receive the message
if ((numbytes = read(sock_fd, foodResponse, RESPONSE_BUFFER)) == -1) {
perror("receive");
exit(EXIT_FAILURE);
}
//end the buffer string
foodResponse[numbytes] = '\0';
//print the buffer
printf("\nThis is the information you require: %s", foodResponse);
} while (foodType[0] != 'q' || foodType[0] != 'Q');
My guess is that your socket is blocking because it expects more information or its not getting anything else. In that case perror() will not fire, but your program will continue to wait for info.

Resources