Socket operation on non-socket

1

I'm learning how to program sockets but I'm having problems when I want to exchange the messages between the client and the server, the two codes work as "should", but the problem is when sending a message and receive.

client.cpp

#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <errno.h>

struct sockaddr_in server;

#define buffer 200

int main(){

    std::string menssagm;

    int clientfd=(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));

    if(clientfd==-1){
        perror("socket");
        std::cout << "Falha\n";
    }else{
        std::cout << "Ok...\n";
    }

    server.sin_family=AF_INET;
    server.sin_port=htons(2000);
    server.sin_addr.s_addr=inet_addr("127.0.0.1");

    int serverfd=(connect(clientfd, (struct sockaddr*)&server, sizeof(server)));

    if(serverfd==-1){
        std::cout << "Erro...\n";
        perror("connect");
    }else{
        std::cout << "Conexão estabelecida com sucesso\n";

        if((recv(serverfd,(void*)menssagm.c_str(), buffer, 0)==-1)){
            std::cout << "Erro ao receber menssagem\n";
            perror("recv");
        }else{
            std::cout << "Menssagem recebida\n";
            std::cout << menssagm << "\n";
        }

        if((send(serverfd, "script kiddie", buffer, 0)==-1)){
            std::cout << "Erro ao enviar menssagem\n";
            perror("send");
        }else{
            std::cout << "Menssagem enviada";
        }

    }
}

server.cpp

#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

struct sockaddr_in local;
struct sockaddr_in remoto;

std::string hello="Hello";
std::string word;

int main(){

    int localFd=((socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)));

    local.sin_family=AF_INET;
    local.sin_port=htons(2000);
    local.sin_addr.s_addr = inet_addr("127.0.0.1");

    bind(localFd,(struct sockaddr*)&local, sizeof(local));

    listen(localFd,1);

    int remotoFd;
    socklen_t len=sizeof(remoto);

    if((remotoFd=accept(localFd, (struct sockaddr*)&remoto, &len))==-1){
        std::cout << "Erro...\n";
    }else{
        std::cout << "Conexão recebida com sucesso\n";
        send(remotoFd, hello.c_str(), 50, 0);
        recv(remotoFd, (void*)word.c_str(), 50, 0);

        std::cout << word << "\n";
    }
}

The return of the perror function is:

recv(): Socket operation on non-socket
send(): Socket operation on non-socket
    
asked by anonymous 01.10.2017 / 19:33

1 answer

2

Your error lies in finding that connect() returns a descriptor. The return of connect() only indicates whether there was an error (-1) or success (0).

Therefore, the calls of send() and recv() of your client, do not use the descriptor of the server.

Another crucial point in your code is in handling the buffers read by send() and written by recv() , you can not fill a std::string from the constant pointer returned by the c_str() method, it is qualified as const and its contents can not be modified in this way!

Your code block that has the accept() call on your client looks something like this:

if(accept(localFd, (struct sockaddr*)&remoto, &len)==-1)
{
    std::cout << "Erro...\n";
}
else
{
    std::cout << "Conexão recebida com sucesso\n";

    send(localFd, hello.c_str(), hello.length(), 0);

    char buf[50];
    int n = recv(localFd, (void*)buf, sizeof(buf), 0);
    buf[n] = '
#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>

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

#define buffer 200

int main( int argc, char * argv[] ){

    struct sockaddr_in srv;

    int s = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );

    if( s < 0 ) {
        std::cerr << "[ERRO] socket(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    srv.sin_family = AF_INET;
    srv.sin_port = htons(2000);
    srv.sin_addr.s_addr = inet_addr("127.0.0.1");

    std::memset( srv.sin_zero, 0, sizeof(srv.sin_zero) );

    if(connect( s, (struct sockaddr*) &srv, sizeof(srv)) != 0){
        std::cerr << "[ERRO] connect(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    std::cout << "[STATUS] Conexão estabelecida com sucesso..." << std::endl;

    if(send( s, argv[1], strlen(argv[1]), 0 ) < 0){
        std::cerr << "[ERRO] send(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    std::cout << "[STATUS] Mensagem enviada com sucesso!" << std::endl;

    shutdown(s, SHUT_RDWR);
    close(s);

    return 0;
}
'; std::cout << buf << "\n"; }

Here is a simple (tested) example of a client / server using the same concepts as your question:

Client:

#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>

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

int main(void ){

    struct sockaddr_in local;
    char buf[256];

    int s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if( s < 0 ) {
        std::cerr << "[ERRO] socket(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    local.sin_family = AF_INET;
    local.sin_port = htons(2000);
    local.sin_addr.s_addr = inet_addr("127.0.0.1");

    std::memset( local.sin_zero, 0, sizeof(local.sin_zero) );

    if(bind( s,(struct sockaddr*)&local, sizeof(local)) != 0 ) {
        std::cerr << "[ERRO] bind(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    if(listen( s, 1 ) != 0){
        std::cerr << "[ERRO] listen(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    while(1)
    {
        struct sockaddr_in remoto;
        socklen_t len = sizeof(remoto);

        std::cout << "[STATUS] Servidor aguardando clientes..." << std::endl;

        int client = accept( s, (struct sockaddr*) &remoto, &len );

        if( client < 0){
            std::cerr << "[ERRO] accept(): " << std::strerror(errno) << std::endl;
            return 1;
        }

        std::cout << "[STATUS] Nova conexão aceita com sucesso..." << std::endl;

        int n = recv( client, (void*)buf, sizeof(buf), 0 );

        if( n < 0 ){
            std::cerr << "[ERRO] recv(): " << std::strerror(errno) << std::endl;
            return 1;
        }

        buf[n] = '
$ ./client "Um pequeno jabuti xereta viu dez cegonhas felizes."
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!

$ ./client "The quick brown fox jumps over the lazy dog"
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!

./client "O rato roeu a roupa do rei de Roma."
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!
'; std::cout << "[STATUS] Mensagem recebida (bytes: " << n << "): " << buf << std::endl; shutdown( client, SHUT_RDWR ); close(client); } return 0; }

Server:

$ ./server
[STATUS] Servidor aguardando clientes...
[STATUS] Nova conexão aceita com sucesso...
[STATUS] Mensagem recebida (bytes: 50): Um pequeno jabuti xereta viu dez cegonhas felizes.
[STATUS] Servidor aguardando clientes...
[STATUS] Nova conexão aceita com sucesso...
[STATUS] Mensagem recebida (bytes: 43): The quick brown fox jumps over the lazy dog
[STATUS] Servidor aguardando clientes...
[STATUS] Nova conexão aceita com sucesso...
[STATUS] Mensagem recebida (bytes: 35): O rato roeu a roupa do rei de Roma.
[STATUS] Servidor aguardando clientes...

Client Test:

if(accept(localFd, (struct sockaddr*)&remoto, &len)==-1)
{
    std::cout << "Erro...\n";
}
else
{
    std::cout << "Conexão recebida com sucesso\n";

    send(localFd, hello.c_str(), hello.length(), 0);

    char buf[50];
    int n = recv(localFd, (void*)buf, sizeof(buf), 0);
    buf[n] = '
#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>

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

#define buffer 200

int main( int argc, char * argv[] ){

    struct sockaddr_in srv;

    int s = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );

    if( s < 0 ) {
        std::cerr << "[ERRO] socket(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    srv.sin_family = AF_INET;
    srv.sin_port = htons(2000);
    srv.sin_addr.s_addr = inet_addr("127.0.0.1");

    std::memset( srv.sin_zero, 0, sizeof(srv.sin_zero) );

    if(connect( s, (struct sockaddr*) &srv, sizeof(srv)) != 0){
        std::cerr << "[ERRO] connect(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    std::cout << "[STATUS] Conexão estabelecida com sucesso..." << std::endl;

    if(send( s, argv[1], strlen(argv[1]), 0 ) < 0){
        std::cerr << "[ERRO] send(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    std::cout << "[STATUS] Mensagem enviada com sucesso!" << std::endl;

    shutdown(s, SHUT_RDWR);
    close(s);

    return 0;
}
'; std::cout << buf << "\n"; }

Server Test:

#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>

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

int main(void ){

    struct sockaddr_in local;
    char buf[256];

    int s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

    if( s < 0 ) {
        std::cerr << "[ERRO] socket(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    local.sin_family = AF_INET;
    local.sin_port = htons(2000);
    local.sin_addr.s_addr = inet_addr("127.0.0.1");

    std::memset( local.sin_zero, 0, sizeof(local.sin_zero) );

    if(bind( s,(struct sockaddr*)&local, sizeof(local)) != 0 ) {
        std::cerr << "[ERRO] bind(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    if(listen( s, 1 ) != 0){
        std::cerr << "[ERRO] listen(): " << std::strerror(errno) << std::endl;
        return 1;
    }

    while(1)
    {
        struct sockaddr_in remoto;
        socklen_t len = sizeof(remoto);

        std::cout << "[STATUS] Servidor aguardando clientes..." << std::endl;

        int client = accept( s, (struct sockaddr*) &remoto, &len );

        if( client < 0){
            std::cerr << "[ERRO] accept(): " << std::strerror(errno) << std::endl;
            return 1;
        }

        std::cout << "[STATUS] Nova conexão aceita com sucesso..." << std::endl;

        int n = recv( client, (void*)buf, sizeof(buf), 0 );

        if( n < 0 ){
            std::cerr << "[ERRO] recv(): " << std::strerror(errno) << std::endl;
            return 1;
        }

        buf[n] = '
$ ./client "Um pequeno jabuti xereta viu dez cegonhas felizes."
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!

$ ./client "The quick brown fox jumps over the lazy dog"
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!

./client "O rato roeu a roupa do rei de Roma."
[STATUS] Conexão estabelecida com sucesso...
[STATUS] Mensagem enviada com sucesso!
'; std::cout << "[STATUS] Mensagem recebida (bytes: " << n << "): " << buf << std::endl; shutdown( client, SHUT_RDWR ); close(client); } return 0; }
    
01.10.2017 / 23:53