TCP "connecttion refused" 错误(c++ CLion)

TCP "connecttion refused" error (c++ CLion)

  1. 我创建了一个 TCP 服务器,我在 运行 时总是出现以下错误。我如何摆脱这个错误,我不明白哪里错了?

  2. 还说连接被拒绝时收到数据,我没有运行客户端。为什么?

Error: Socket Created Error connect to server: Connection refused Error to accept: Invalid argument Data received

服务器

#include <iostream>
#include "serverh.hpp"
#include "glimpsepackages.h"
#include "soupbintcppackages.h"



int main() {
    //soupBinTCP structures
    DebugPacket D;                               //"+"
    LoginAcceptedPacket A;
    LoginRejectPacket J;
    SequencedDataPacket S;
    ServerHeartBeatPacket H;
    EndOfSessionPacket Z;

    //glimpse structures

    SecondsMessage T;
    CombinationOrderBookDelivery M;
    TickSizeTableEntryPackage L;
    OrderBookDirectoryPackage R;
    OrderBookStatePackage O;
    AddOrderMessageNoMPIDPackage A1;
    AddOrderMessageMPIDPackage F;

    std::string ip="127.0.0.1";
    int port=7888;
    ssize_t size=1024;

    void *data={};

    TcpServer server(ip, port);

    server.connectToClient();
    server.accept();

    for (;;) {

        server.receivingData(size);   

        switch (server.pop()) {
            case '+':
                //  D.length=server.pop();
                D.code = server.pop8();
                D.text = server.pop();
                break;

            case 'A' :
                A.to_little_endian();
                A.code = server.pop8();
                A.sequence_number = server.pop32();

                for (int i = 0; i < 10; i++) {
                    A.session[i] = server.pop();
                }

                break;

            case 'J':
                    J.code = server.pop8();
                    J.rejectreasoncode = server.pop();
                break;

            case 'S':
                S.code = server.pop8();
                S.message = server.pop();
                break;

            case 'H':
                H.code = server.pop8();

            case 'Z':
                Z.code = server.pop8();

            default:
                return 0;
        }
    }

serverh.cpp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string>
#include "serverh.hpp"
#include "util.h"
#include <iostream>


TcpServer::TcpServer(std::string ip, int port):_ip(ip),
_port(port),  _addrSize(sizeof _serverAddress) 
{
    _sockFd=-1;
};


bool TcpServer::connectToClient(){
    _sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(_sockFd==-1)
        perror("Error creating socket");
    else
        std::cerr<<"Socket Created\n";

    _serverAddress.sin_addr.s_addr=inet_addr(_ip.c_str());
    _serverAddress.sin_family=AF_INET;
    _serverAddress.sin_port=htons(_port);


    if(::connect(_sockFd,(struct sockaddr *)&_serverAddress,   sizeof(_serverAddress))<0) {
        perror("Error connect to server");
        return false;
    }
    else
        std::cerr<<"Connected\n";

    if(::bind(_sockFd,(struct sockaddr *)&_serverAddress,_addrSize)<0)
        perror("Error bind to server");
    else
        std::cerr<<"Socket bind\n";

    if(::listen(_sockFd,5)==0)
        std::cerr<<"Listining\n";
    else
        perror("Error on Listening");

    return true;
}

bool TcpServer::accept(){
    if(::accept(_sockFd,(struct sockaddr *) &_serverAddress, &_addrSize)<0)
        perror("Error to accept");
    else
        std::cerr<<"Accepted\n";

    return  true;
}

void *TcpServer::receivingData(ssize_t size){
    char *buffer=new char[size];
    if(::recv(_sockFd,buffer, size,0)>0);
    std::cerr<<"Data received\n";

    return buffer;
}

void TcpServer::incOffset(int rest_length) {
    void *restbuff = alloca(rest_length);
    if (::recv(_sockFd, restbuff, rest_length, 0) < 0)
        std::cerr << "Data received\n";
}

char TcpServer::pop(){
    char ch;
    if(::recv(_sockFd, &ch, 1, 0)>0)
        return ch;
}

int8_t TcpServer::pop8() {
    int8_t ch;
    if (::recv(_sockFd, &ch, 8, 0) > 0)
        return getLeValue(ch);      // func include endian functions
}

int16_t TcpServer::pop16(){
    int16_t ch;
    if(::recv(_sockFd, &ch, 16, 0)>0)
        return getLeValue(ch);
}

int32_t TcpServer::pop32(){
    int32_t ch;
    if(::recv(_sockFd, &ch, 32, 0)>0)
        return getLeValue(ch);
}

int64_t TcpServer::pop64() {
    int64_t ch;
    if (::recv(_sockFd, &ch, 64, 0) > 0)
        return getLeValue(ch);
}

Serverh.hpp

#ifndef SERVERH_H
#define SERVERH_H

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

class TcpServer{
    public:
        TcpServer(const std::string _ip,int _port);

        bool connectToClient();
        bool accept();
        void *receivingData(ssize_t size);
        bool sendToClient();
        char pop();
        int8_t pop8();
        int16_t pop16();
        int32_t pop32();
        int64_t pop64();

        void incOffset(int rest_length);

    private:

        std::string _ip;
        int _port;
        int _sockFd;
        sockaddr_in _serverAddress;
        socklen_t _addrSize;
};

#endif

问题

Error: Socket Created Error connect to server: Connection refused Error to accept: Invalid argument Data received

这里有两个错误,连接失败是因为另一个地址不接受连接,接受失败是因为一个或多个输入参数错误。

无法连接是可以理解的。客户端很少在端口上监听连接。 Clients usually initiate the connection.

accept失败是由于connectToClient连接失败后退出。它从来没有 binds 和 listens,所以还没有为 accept.

设置套接字

解决这个问题

服务器不应尝试连接。它应该监听连接到它的尝试。这让 connectToClient 很奇怪。它尝试连接到客户端,然后在同一个套接字上绑定并侦听。你不能两者都做,所以我会放弃

if(::connect(_sockFd,(struct sockaddr *)&_serverAddress,   sizeof(_serverAddress))<0) {
    perror("Error connect to server");
    return false;
}
else
    std::cerr<<"Connected\n";

重新考虑

_serverAddress.sin_addr.s_addr=inet_addr(_ip.c_str());

因为这只会监听一个传入地址,这可能是您想要的,但通常不是。我还会重命名函数以反映用途的变化。

注:

if(::accept(_sockFd,(struct sockaddr *) &_serverAddress, &_addrSize)<0)

传入指向服务器地址的指针。该位置将被客户端的地址覆盖。这是无害的,但您可能不想这样做。据我所知,您没有使用返回的地址,所以您最好传入 NULL 并继续传递。

if(::accept(_sockFd, NULL, NULL)<0)