How to compare data sent by client in server C programing - c

I want to send a option from the client to a server. The server have to do some comparisons and send a string back to the client. I can receive the data from the client, but my server crashes in the moment of comparison (it gets to the else with the "error input" and ends the connection). Can someone tell me what I'm doing wrong?
Incorrect Inputclose error: Bad file descriptor
Program exited with code 01.
Server:
void
result(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
int temp;
time_t ticks;
again:
while ((n =read(sockfd, buf, MAXLINE)> 0))
{
temp = rand() % 22;
if (buf=="A\n" || buf=="a\n")
{
snprintf(buf, sizeof(buf), "You option is number is -%i, time is %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
if (buf=="B\n" || buf=="f\")
{
snprintf(buf, sizeof(buf), "You option is number is -%i, time is %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
else
{
printf("Incorrect Input");
Close(sockfd);
}
}
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("read error");
}
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
char recvline[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("EDMTS is running on 129.128.4.80, listening on port 5678\n");
printf("\n");
printf("Waiting for incoming connections...Press Ctrl+C to end server\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("\n");
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
result(connfd);
Close(connfd);
printf("Conexion cerrada...Esperando siguiente cliente\n");
}
}
Client
void
get_temp(FILE *fp, int sock)
{
char sendline[MAXLINE], recvline[MAXLINE];
while (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sock, sendline, strlen(sendline));
if (Readline(sock, recvline, MAXLINE) == 0)
err_quit("Server Terminated Prematurely");
Fputs(recvline, stdout);
}
}
int
main(int argc, char **argv)
{
int sockfd, n;
socklen_t len;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr, cliaddr;
char scale[2];
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
printf("Connect...\n");
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
len = sizeof(cliaddr);
Getsockname(sockfd, (SA *) &cliaddr, &len);
printf("Local Address is: %s\n",
Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
printf("Enter option A or B): ");
get_temp(stdin, sockfd);
exit(0);
}
When I run the debugger to find out my variables, I find:
Breakpoint 1, result (sockfd=7) at servertest.c:236 236
printf("Random es %i\n",temp);
(gdb) p buf
$1 = "A\n", '\0' , "\203\217��", '\0' ,
"h\206��h\206��\204\210������#���\000\000\000\000�\206����߷\020\207��#���",
'\0' ,
"������������\000\000\000\000\000\000\000\000�\017��", '\0' , "h\206��", '\0' ,
"\001\000\000\000\000\000\000\000�\207��", '\0' ,
"����\t\000\000\000#���\030���\000\000\000\000h\206��\003", '\0'
, "\n\000\000\000g\206��", '\0' ,
" "...
(gdb) p temp
$2 = 17
Thank you very much

First of all, you can't compare C strings using == (you will compare pointer adresses, and the address of buf[0] and the address of your static string "a\n" will certainly not be equal. To compare the strings, use strncmp().
Your crash happens because after you call Close(), the read() function is called again on the socket file descriptor. To remove the crash, put a break; after the Close(), like so:
else
{
printf("Incorrect Input");
Close(sockfd);
break;
}

Also, you are closing the socket twice. First here:
// void result(int sockfd)
else
{
printf("Incorrect Input");
Close(sockfd); // <<<
}
Then here:
// int main(int argc, char **argv)
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
result(connfd);
Close(connfd); // <<<
printf("Conexion cerrada...Esperando siguiente cliente\n");

Related

Server does not get into the if statement, it structs. Socket programming in C

I want to compare some data that the client sends to a server. But my server got stuck after the random function in my result function. It does nos printf (printf("Into IF");) or get into the ifs, why is this?
Waiting for incoming connections...Press Ctrl+C to end server
Connection from 127.0.0.1, port 60697 Message Recieved:c Ramdom es 12
My code:
void
result(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
int temp;
time_t ticks;
int i;
again:
while ((n =read(sockfd, buf, MAXLINE)> 0))
{
buf[n] = '\0';
printf("Message Recieved:%s\n",buf);
srand (time(NULL));
temp = rand() % 15+1;
printf("Ramdom es %i\n",temp);
printf("Into IF");
if ((strncmp (buf,"A",1) == 0) || (strncmp (buf,"a",1) == 0))
{
snprintf(buf, sizeof(buf), "You choose -%i tymes optin A on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
else if ((strncmp (buf,"B",1) == 0) || (strncmp (buf,"b",1) == 0))
{
snprintf(buf, sizeof(buf), "You choose -%i tymes optin B on on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
else
{
printf("Incorrect Input");
Close(sockfd);
break;
}
}
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("read error");
}
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
/*char message[MAXLINE];*/
char recvline[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("Server is running on 127.0.0.1, listening on port 5678\n");
printf("\n");
printf("Waiting for incoming connections...Press Ctrl+C to end server\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("\n");
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
result(connfd);
Close(connfd);
}
}
Thanks!
To print the printf add a "\n" (linefeed) so that terminal flushes and displays it. There are several occasions in your code where a \n will help your debug-printfs coming out.
This answers "why does printf does not printf". I think this is not your real problem though.

Message send, receiver not getting the message. Socket programing

I'm receiving a message from the client, comparing it and sending a message according to the result in the comparison. The server sends the message (apparently), but the client stays in the reading processes.
Server:
Waiting for incoming connections...Press Ctrl+C to end server
Connection from 127.0.0.1, port 54918 Message Recieved:c Random es 5
Into IFs 1er IF
void
result(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
int temp;
time_t ticks;
int i;
again:
while ((n =read(sockfd, buf, MAXLINE)> 0))
{
buf[n] = '\0';
printf("Message Recieved:%s\n",buf);
srand (time(NULL));
temp = rand() % 15+1;
printf("Ramdom es %i\n",temp);
printf("Into IF\n");
if ((strncmp (buf,"A",1) == 0) || (strncmp (buf,"a",1) == 0))
{
snprintf(buf, sizeof(buf), "Option A chosen times %i on on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
printf("1st IF\n");
}
else if ((strncmp (buf,"B",1) == 0) || (strncmp (buf,"b",1) == 0))
{
snprintf(buf, sizeof(buf), "Option B chosen times %i on on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
printf("2nd IF\n");
}
else
{
printf("Incorrect Input");
Close(sockfd);
break;
}
}
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("read error");
printf("salio de funcion result\n");
}
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
/*char message[MAXLINE];*/
char recvline[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("Server is running on 127.0.0.1, listening on port 5678\n");
printf("\n");
printf("Waiting for incoming connections...Press Ctrl+C to end server\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("\n");
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
result(connfd);
Close(connfd);
}
}
Client:
Connect... Local Address is: 127.0.0.1:54918
Starting read...
Enter Option A or B: b
void
get_temp(FILE *fp, int sock)
{
char sendline[MAXLINE], recvline[MAXLINE];
while (Fgets(sendline, MAXLINE, fp) != NULL) {
Writen(sock, sendline, strlen(sendline));
if (Readline(sock, recvline, MAXLINE) == 0)
err_quit("Server Terminated Prematurely");
Fputs(recvline, stdout);
}
}
int
main(int argc, char **argv)
{
int sockfd, n;
socklen_t len;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr, cliaddr;
char scale[2];
if (argc != 3)
err_quit("usage: a.out <IPaddress>");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
printf("Connect...\n");
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
len = sizeof(cliaddr);
Getsockname(sockfd, (SA *) &cliaddr, &len);
printf("Local Address is: %s\n",
Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
printf("Starting read...\n");
printf("Enter option A or B: ");
get_temp(stdin, sockfd);
exit(0);
}
Thanks.
Stop coding and write a protocol specification. The specification should specify, at the byte level, what information is exchanged and how. The way you're doing it now, it's impossible for you code to be "right" or "wrong" because there is no specification for it to comply with or not comply with.
The most important thing to cover in the protocol specification is whether you have a "message" and if so, how each side finds the beginning and end of them. You can use closing the connection as a message boundary. You can use a delimiter (such as a zero byte or a newline) as a message boundary. You can prefix each message with its length.
But without a specification, your server and client will only agree on who does what, when, and how by luck.

Segmentation fault trying to send message to client from server

I need to send a message to a client and then the client have to respond with an option. I get till the client and server connects, but both program end with "Segmentation Fault". Does anyone knows what this error means? Can someone give an idea to how to create a code that will make client and server interact. After receiving the option chosen by the client the server have to analyze it and send again a result to client.
My codes are:
Server
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
time_t ticks;
char message[MAXLINE]="This is the server";
char temp_scale[2];
char recvdata[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5555);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
snprintf(message, sizeof(message), "%s\r\n");
Writen(connfd, message, strlen(message));
while ( (n = read(connfd, recvdata, MAXLINE)) > 0)
{
recvdata[n] = 0; /* null terminate*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
Close(connfd);
}
}
Client
int
main(int argc, char **argv)
{
int sockfd, rd;
socklen_t len;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr, cliaddr;
char scale[2];
/*if (argc != 2)
err_quit("usage: a.out <IPaddress>");*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2])); /*port passed through command line*/
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/
err_quit("inet_pton error for %s", argv[1]);
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
len = sizeof(cliaddr);
Getsockname(sockfd, (SA *) &cliaddr, &len);
printf("Local Address is: %s\n",
Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
printf("Iniciando read...\n");
while ( (rd = read(sockfd, recvline, MAXLINE)) > 0)
{
recvline[rd] = 0; /* null terminate*/
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (rd < 0)
err_sys("read error");
printf("Enter option 'A' or 'B'");
send_scale(sockfd);
exit(0);
}
Thanks
Your server is probably faulting because of this:
snprintf(message, sizeof(message), "%s\r\n"); // <== no parameters
It is flat-out wrong. The snprintf() call has a format specifier that is expecting a char * to a null-terminated string, and you're passing it absolutely nothing. It is therefore grabbing a random value out of the stack, treating it as a pointer, and dereferencing it in attempt to fulfill the formatted request.
Without knowing the details of the API you're using (it clearly isn't standard BSD sockets just by the names alone) there isn't much more to go on.
Run your code in a debugger (for example gdb ./a.out) and find out in no time.
I don't know if it might help, but in C the null termination for strings is '\0', when you print your response:
recvdata[n] = 0; /* null terminate ----> this must be '\0'*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");
you pad it whith a "0", so it will probably lead you to a segfault when fputs parse your string in order to print it.
Hope it helps!

Client does not receive message form server

I'm sending a message (a greeting) from a server to a client. The server sends the data but the client is not receiving it and then the server jumps to a read because client have to reply with an input of the user. Can you tell me why I never receive the greeting message?
Server:
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
time_t ticks;
char message[50];
char temp_scale[2];
char recvdata[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("Listening on port 5678...Press Ctrl+C to end server\n");
printf("Waiting for incoming connections...\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
snprintf(message, sizeof(message), "%s\r\n", "Welcome!");
Writen(connfd, message, strlen(message));
while ( (n = read(connfd, recvdata, MAXLINE)) > 0)
{
recvdata[n] = 0; /* null terminate*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
Close(connfd);
}
}
Client:
int
main(int argc, char **argv)
{
int sockfd, n;
socklen_t len;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr, cliaddr;
char scale[2];
/*if (argc != 2)
err_quit("usage: a.out <IPaddress>");*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2])); /*port passed through command line*/
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/
err_quit("inet_pton error for %s", argv[1]);
printf("Connect...\n");
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");
len = sizeof(cliaddr);
Getsockname(sockfd, (SA *) &cliaddr, &len);
printf("Local Address is: %s\n",
Sock_ntop((SA *) &cliaddr, sizeof(cliaddr)));
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");
printf("Enter the thermal Unit ('C' Celsius, 'F' Farehnheit: ");
send_data(sockfd);
exit(0);
}
Thanks!

passing argument 1 of ‘strncmp’ makes pointer from integer without a cast C programing

I want to compare some data that the client sends to a server. Bout i have this error when I use strncmp t compare what I read from the socket and the strings I'm using to compare. Can someone tell me why is this error?
warning: passing argument 1 of ‘strncmp’ makes
pointer from integer without a cast
Server:
void
result(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
int temp;
time_t ticks;
int i;
again:
while ((n =read(sockfd, buf, MAXLINE)> 0))
{
buf[n] = '\0';
printf("Message Recieved:%s\n",buf);
srand (time(NULL));
temp = rand() % 40+1;
printf("Ramdom es %i\n",temp);
if ((strncmp (buf[0],"Axx",1) == 0) || (strncmp (buf[0],"axx",1) == 0))
{
snprintf(buf, sizeof(buf), "Option A choosen in %i on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
if ((strncmp (buf[0],"Bxx",1) == 0) || (strncmp (buf[0],"bxx",1) == 0))
{
snprintf(buf, sizeof(buf), "Option B choosen in %i on %.24s\r\n", temp,ctime(&ticks));
Writen(sockfd, buf, n);
}
else
{
printf("Incorrect Input");
Close(sockfd);
break;
}
}
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
err_sys("read error");
}
int
main(int argc, char **argv)
{
int listenfd, connfd;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
/*char message[MAXLINE];*/
char recvline[MAXLINE + 1];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
servaddr.sin_port = htons(5678);
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
printf("EDMTS is running on 127.0.0.1, listening on port 5678\n");
printf("\n");
printf("Waiting for incoming connections...Press Ctrl+C to end server\n");
for ( ; ; )
{
len = sizeof(cliaddr);
connfd = Accept(listenfd, (SA *) &cliaddr, &len);
/*Client connects to server*/
printf("\n");
printf("Connection from %s, port %d\n",
Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
ntohs(cliaddr.sin_port));
result(connfd);
Close(connfd);
}
}
Thank you very much.
strncmp expects a const char* as first argument whereas you pass just a char.
Change it to:
if ((strncmp (buf,"Bxx",1) == 0) || (strncmp (buf,"bxx",1) == 0))
You should pass not character (buf[0]) but pointer to character (buf for example) for comparison.
buf[0] is a char, but strncmp expects a char*. Instead of
strncmp (buf[0],"Axx",1)
make it
strncmp (buf,"Axx",1)
etc.
But, if you pass 1 as the length parameter to strncmp, you could also just check
if (buf[0] == 'A' || buf[0] == 'a') // resp. 'B', 'b'
and avoid the function call.

Resources