Home > Enterprise >  Linux Sockets with Printf giving garbage after string
Linux Sockets with Printf giving garbage after string

Time:11-26

I've written a simple Linux Client - Server connection that sends a string from server to client, client prints string. The client then sends a String to the server, the server prints the String

I run my code in a Linux virtual machine, The distro is Debian.

What's happening is when the client prints the string, the program behaves normally, however when the server prints the string in the same way, it prints the string then on the next line adds garbage data such as ♦.

I've looked hard at all the pointers and writes to see if I have any buffer overflows which would cause this problem, however I am new to c and cannot find any myself.

Whats wierd about the error is it only happens in server and never in client even though they print the string exactly the same way.

As stated before I've looked line by line searching for buffer overflows, as well as looking at other peoples problems. I've tried using fflush(stdout) and messing with pointers but nothing I've tried works.

Removing the ".*" in server printf() results in a segfault

This is the client Code

#include <stdio.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <string.h>
#include <unistd.h>

int main() {
    //create server info
    struct sockaddr_in server_info = {0};
    server_info.sin_family = AF_INET;
    server_info.sin_addr.s_addr = htonl(0x7f000001);
    server_info.sin_port = htons(25565);

    socklen_t server_info_len = sizeof(server_info);

    //create client socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    //connect to server
    if (connect(sockfd, (struct sockaddr*)&server_info, server_info_len) < 0) {
        perror("connect");
        return -1;
    }

    char buffer[1024];

    //recieve message
    ssize_t recvd = recv(sockfd, buffer, sizeof(buffer)-1, 0);

    if (recvd < 0) {
        perror("recv");
        return -1;
    }

    //print message
    printf("%.*s", sizeof(buffer)-1, buffer);

    //send client message

    char* sentFromClient = "Sent from client!\n";
    ssize_t sent = send(sockfd, (void*)sentFromClient, strlen(sentFromClient), 0);
    if (sent < 0) {
        perror("send");
        return -1;
    }

    //close socket
    if (close(sockfd) < 0) {
        perror("close");
        return -1;
    }

    return 0;
}

This is the Server Code

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

int main() {
    //create server structures
    struct sockaddr_in server_info = {0};

    server_info.sin_family = AF_INET;
    server_info.sin_port = htons(25565);

    socklen_t server_info_len = sizeof(server_info);

    //create client structures for server use
    struct sockaddr client_info = {0};
    socklen_t client_info_len = sizeof(client_info);

    //create our socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    //bind socket
    if (bind(sockfd, (struct sockaddr*)&server_info, server_info_len) < 0) {
        perror("bind");
        return -1;
    }

    //listen on port
    if (listen(sockfd, 0) < 0) {
        perror("listen");
        return -1;
    }

    //accept client
    int clientfd = accept(sockfd, &client_info, &client_info_len);
    if (clientfd < 0) {
        perror("accept");
        return -1;
    }

    //send client message
    char* sentViaServer = "From Server!\n";
    ssize_t sent = send(clientfd, (void*)sentViaServer, strlen(sentViaServer), 0);

    if (sent < 0) {
        perror("send");
        return -1;
    }

    //recieve client message
    char buffer[1024];

    ssize_t recvd = recv(clientfd, buffer, sizeof(buffer)-1, 0);
    if (recvd < 0) {
        perror("recv");
        return -1;
    }

    //print client message
    printf("%.*s", sizeof(buffer)-1, buffer);

    //close socket
    if (close(clientfd) < 0) {
        perror("close");
        return -1;
    }

    if (close(sockfd) < 0) {
        perror("close");
        return -1;
    }
    return 0;
}

These are the outputs of Server and Client respectively

enter image description here

enter image description here

CodePudding user response:

In both the client and server, you're sending exactly as many characters as are in their respective strings. This does not include a terminating null byte. And because the buffer in both the client and server are uninitialized, after you read in the string that was sent and attempt to print it, you end up reading uninitialized values in each buffer. On the client it happens to not show anything, presumably because some of those uninitialized bytes happened to be 0, but that isn't the case on the server side.

You can handle this by either sending the terminating null byte in both cases:

// client
ssize_t sent = send(sockfd, sentFromClient, strlen(sentFromClient) 1, 0);

// server
ssize_t sent = send(clientfd, sentViaServer, strlen(sentViaServer) 1, 0);

Or by terminating the string manually after reading.

// client and server
if (recvd < 0) {
    perror("recv");
    return -1;
}
buffer[recvd] = 0;
  • Related