sockets: Why does server[buffer] > client[message]? + more questions [Archive] - C Board

PDA

View Full Version : sockets: Why does server[buffer] > client[message]? + more questions


heras
03-08-2008, 03:51 PM
[edit] Why must server > client[message]?

Hi,
My client tries to send 'ping' to my server.
client:
int main()
{
int sockfd;
struct sockaddr_in server_address;
char server_ip[16];
char *message = "ping";
//stuff
send(sockfd, message, strlen(message) + 1, 0);

server:

char buffer[smaller than 8];
//stuff
recv(new_fd, buffer, strlen(message);
printf("%s\n", buffer);
With a buffer smaller than 8 the server only prints a new line, even though I'm only expecting 'ping' + '\0', 5 characters. With 8 or more 'ping' is received and printed succesfully. Is there still some header that needs to be stripped at this point? (or other?)

With
send(sockfd, message, strlen(message), 0);
without the [b]+ 1 the message gets sent and printed, plus some garbage characters. Why is this?
If the entire code is needed, which is not that big, please let me know.

Slightly off-topic:
What do you think about
if (connect(sockfd, (struct sockaddr *) &servaddr,
sizeof(servaddr)) < 0) {

fprintf(stderr, "connect error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
versus
if ((connect(sockfd, (struct sockaddr *)&server_address, \
sizeof server_address)) == -1) {
perror("Connection error: ");
exit(EXIT_FAILURE);
? I think the question is how to do propper error handling. I see much examples but do not understand the difference.

Please note that I'm a beginner amongst beginners.
Thanks,
heras

robwhit
03-08-2008, 07:41 PM
> recv(new_fd, buffer, strlen(message);

should be:

recv(new_fd, buffer, sizeof(buffer));

> without the + 1 the message gets sent and printed, plus some garbage characters. Why is this?

strlen does not count the nul terminating character.

> If the entire code is needed, which is not that big, please let me know.

that would be preferrable.

heras
03-09-2008, 03:35 AM
Hi robwhit, thanks for your reply.
> recv(new_fd, buffer, strlen(message);
Yes, my bad. I forgot to replace that "message" with buffer, intended for clarity. I call them "message" in both the client and the server in my actual program:
[edit] and I missed the sizeof XD. Fixed.
client.c :
/*
Socket exercise - Stream client
*/

#include <stdio.h> /* printf, scanf, etc */
#include <stdlib.h> /* ? */
#include <string.h> /* memset() */
#include <sys/types.h> /* socket(), connect(), etc */
#include <sys/socket.h> /* socket(), connect(), etc */
#include <netinet/in.h> /* inet_addr() */
#include <arpa/inet.h> /* inet_addr() */
#include <errno.h> /* perror() */

int main()
{
int sockfd;
struct sockaddr_in server_address;
char server_ip[16];
char *message = "ping";
char reply[1024];

printf("Enter server IP:\n");
scanf("%15s", server_ip); // fix me

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("Socket error: ");
exit(EXIT_FAILURE);
}
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9999);
server_address.sin_addr.s_addr = inet_addr(server_ip);
memset(server_address.sin_zero, '\0', sizeof server_address.sin_zero);
if ((connect(sockfd, (struct sockaddr *)&server_address, \
sizeof server_address)) == -1) {
perror("Connection error: ");
exit(EXIT_FAILURE);
}
send(sockfd, message, strlen(message) + 1, 0);
recv(sockfd, reply, sizeof(reply), 0);
printf("%s\n", reply);

return 0;
}


server.c :
/*
Socket exercise - Stream server
*/

#include <stdio.h> /* printf, scanf, etc */
#include <stdlib.h> /* ? */
#include <string.h> /* memset() */
#include <sys/types.h> /* socket(), connect(), etc */
#include <sys/socket.h> /* socket(), connect(), etc */
#include <netinet/in.h> /* inet_addr() */
#include <arpa/inet.h> /* inet_addr() */
#include <errno.h> /* perror() */
#include <unistd.h>

#define PORT 9999
#define BACKLOG 10

int main()
{
int sockfd, new_fd, yes = 1;
struct sockaddr_in local_address, remote_address;
socklen_t sin_size;
char message[1024];
char *reply = "pong";

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket: ");
exit(EXIT_FAILURE);
}
if ((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, \
sizeof(int))) == -1) {
perror("setsockopt :");
exit(EXIT_FAILURE);
}

local_address.sin_family = AF_INET;
local_address.sin_port = htons(PORT);
local_address.sin_addr.s_addr = INADDR_ANY;
memset(local_address.sin_zero, '\0', sizeof local_address.sin_zero);
if ((bind(sockfd, (struct sockaddr *)&local_address, \
sizeof local_address)) == -1) {
perror("bind: ");
exit(EXIT_FAILURE);
}
if ((listen(sockfd, BACKLOG)) == -1) {
perror("listen: ");
exit(EXIT_FAILURE);
}

while(1) {
sin_size = sizeof remote_address;
if ((new_fd = accept(sockfd, (struct sockaddr *)&remote_address, \
&sin_size)) == -1) {
perror("accept: ");
continue;
}
if (!fork()) {
close(sockfd);
if (recv(new_fd, message, sizeof(message), 0) == -1) \
perror("recv: ");
else {
printf("%s\n", message);
send(new_fd, reply, strlen(reply) + 1, 0);
}
close(new_fd);
exit(EXIT_SUCCESS);
}
close(new_fd);
}

return(EXIT_SUCCESS);
}

robwhit
03-09-2008, 04:26 PM
recv might not fill up the buffer.

What do recv/send return?

heras
03-10-2008, 04:19 AM
Send() returns 5, recv() returns 0. But I think I'm doing it wrong.
if (r = (recv(new_fd, message, sizeof(message), 0) == -1)) \
perror("recv: ");
else {
printf("%s\n", message);
(s = send(new_fd, reply, strlen(reply) + 1, 0));
}
printf("%d\n", s);
printf("%d\n", r);
[edit] the client returns 5 for both send() and recv()