Reputation: 37
I'm learning about c socket programming. I'm very new to this so forgive me if the answer may seem obvious. So basically I want the client to send to the server two strings ( username and a password). Problem is that the server only receives the username and then closes connection.
Can anyone explain why is this happening and how can I get it to work as intended ?
client:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 20000
#define LENGTH 512
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
/* Variable Definition */
int sockfd;
int nsockfd;
char revbuf[LENGTH];
struct sockaddr_in remote_addr;
/* Get the Socket file descriptor */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor! (errno = %d)\n",errno);
exit(1);
}
/* Fill the socket address struct */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT);
inet_pton(AF_INET, "127.0.0.1", &remote_addr.sin_addr);
bzero(&(remote_addr.sin_zero), 8);
/* Try to connect the remote */
if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr)) == -1)
{
fprintf(stderr, "ERROR: Failed to connect to the host! (errno = %d)\n",errno);
exit(1);
}
else
printf("[Client] Connected to server at port %d...ok!\n", PORT);
char username[20], pw[20],buff;
int rc,rc2;
printf("username: ");
scanf("%s",username);
rc=send(sockfd, username, strlen(username)+1, 0);
printf("\n");
printf("password: ");
scanf("%s",pw);
rc2=send(sockfd, pw, strlen(pw)+1, 0);
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
server:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 20000
#define BACKLOG 5
#define LENGTH 512
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main ()
{
/* Defining Variables */
int sockfd;
int nsockfd;
int num;
int sin_size;
struct sockaddr_in addr_local; /* client addr */
struct sockaddr_in addr_remote; /* server addr */
char revbuf[LENGTH]; // Receiver buffer
/* Get the Socket file descriptor */
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
fprintf(stderr, "ERROR: Failed to obtain Socket Descriptor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Obtaining socket descriptor successfully.\n");
/* Fill the client socket address struct */
addr_local.sin_family = AF_INET; // Protocol Family
addr_local.sin_port = htons(PORT); // Port number
addr_local.sin_addr.s_addr = INADDR_ANY; // AutoFill local address
bzero(&(addr_local.sin_zero), 8); // Flush the rest of struct
/* Bind a special Port */
if( bind(sockfd, (struct sockaddr*)&addr_local, sizeof(struct sockaddr)) == -1 )
{
fprintf(stderr, "ERROR: Failed to bind Port. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Binded tcp port %d in addr 127.0.0.1 sucessfully.\n",PORT);
/* Listen remote connect/calling */
if(listen(sockfd,BACKLOG) == -1)
{
fprintf(stderr, "ERROR: Failed to listen Port. (errno = %d)\n", errno);
exit(1);
}
else
printf ("[Server] Listening the port %d successfully.\n", PORT);
int success = 0;
while(1)
{
sin_size = sizeof(struct sockaddr_in);
if ((nsockfd = accept(sockfd, (struct sockaddr *)&addr_remote, &sin_size)) == -1)
{
fprintf(stderr, "ERROR: Obtaining new Socket Despcritor. (errno = %d)\n", errno);
exit(1);
}
else
printf("[Server] Server has got connected from %s.\n", inet_ntoa(addr_remote.sin_addr));
int rc,rc2;
char username[20],pw[20];
rc = recv(nsockfd, username, strlen(username), 0);
printf(username);
rc2 = recv(nsockfd, pw, strlen(pw), 0);
printf("\n");
printf(pw);
success = 1;
close(nsockfd);
printf("[Server] Connection with Client closed. Server will wait now...\n");
// while(waitpid(-1, NULL, WNOHANG) > 0);
//}
}
}
Upvotes: 0
Views: 6754
Reputation: 11058
In the server:
recv(nsockfd, username, strlen(username), 0);
.
The third parameter must specify size of the buffer. However, username
does not contain any data yet, so strlen(username)
is undefined behavior and most probably returns something inappropriate. Use sizeof(username)
instead. The same for password.
Also note that recv
will read up to 20 bytes from the stream. So, unless username
is guaranteed to be always 19 characters + '\0'
, the first recv
may (somewhat unexpectedly) read some characters from password
as well, stealing them from the second recv
. There are no message boundaries in a TCP stream.
Upvotes: 1