c++ - C++ 中的 TCP/IP 服务器不等待客户端

标签 c++ sockets tcp qt-creator

我在 Internet 上找到了一些代码,其中包含一些有关在 C++ 中创建 TCP/IP 服务器的基础知识。 我拿了这段代码,添加了一些库和一些代码行。结果是,我能够在 Windows 上的 Qt Creator 中编译和运行代码/服务器作为控制台程序。尽管如此,我还是无法连接到服务器,因为它只是运行代码而不等待和接受来自 TCP 客户端的连接。

这是代码: 编辑:代码已更新,现在可以使用了。针对 == -1 进行测试是解决方案。

#define PORT 2000
#define MAX_QUEUE 5
#define BUF_SIZE 1024

int main(int argc, char* const argv[])
{
cout << "Hello World!" << endl;    
        WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
cout << "wsaret: " << wsaret << endl;

cout << "Start TCP/IP Server" << endl;

/* file descriptors for sockets */
SOCKET sock_1, sock_2;  //switched from in to SOCKET //unsigned int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];

//struct sockaddr_in server;
struct sockaddr_in server;

/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//if(sock_1 < 0)
if(sock_1 == -1)
{
    cout << "socket: " << WSAGetLastError() << endl; //instead of //cout << "socket: " << strerror(errno) << endl; //cout << "socket wsaret: " << wsaret << endl;
    exit(1);
}

/* build address in internet domain */
server.sin_family = AF_INET;

/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = htons(2000);  //server.sin_port = PORT; //Port: 2000

/* bind socket */
//if(bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
int bindreturn = (bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
if(bindreturn == -1)
{
    cout << "bind: " << WSAGetLastError() << endl; //instead of //cout << "bind: " << strerror(errno) << endl; //cout << "bind wsaret: " << wsaret << endl;
    exit(1);
}

listen(sock_1,MAX_QUEUE);
    /* start accepting connection */
    sock_2 = accept(sock_1,0,0);
    if(sock_2 < 0)
    {
        cout << "accept: " << WSAGetLastError() << endl;
        exit(1);
    }

    /* read from sock_2 */
    while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
    {
        if(rec_value < 0)

        {
         cout << "recv: " << WSAGetLastError() << endl;
         exit(1);
        }
        else
        {
            cout << "else" << endl;
            send(sock_2,"1,2,3",strlen("1,2,3"),0);
        }
    }

    cout << "Ending connection" << endl;
    closesocket(sock_1);
    closesocket(sock_2);
    cout << "End TCP/IP Server" << endl;

    WSACleanup();
return 0;
}

控制台在一秒或更短时间内运行程序后/期间显示以下内容:

Hello World!
wsaret: 0
Start TCP/IP Server
bind: 0

服务器等待连接伙伴,我该怎么办?

提前致谢。

问候 素材

编辑:开头加了几行代码,之前忘记了。 编辑:代码更新 编辑:代码更新

最佳答案

我将对您发布的原始代码进行详细评论。

cout << "Start TCP/IP Server" << endl;

//int sock_1,sock_2;     /* file descriptors for sockets */
int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];

//struct sockaddr_in server;
sockaddr_in server;

/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//0);

此处缺少测试。您必须按照以下方式测试 -1 的结果:

if (sock_1 == -1)
{
    cout << "socket creation error: " << WSAGetLastError() << endl;
    exit(1); // or some other measure to prevent continuation
}

回到你的代码:

/* build address in internet domain */
server.sin_family = AF_INET;

/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = PORT; //Port: 2000

应该是

server.sin_port = htons(PORT);

回到你的代码:

/* bind socket */
int bindreturn = bind(sock_1, (struct sockaddr *)&server, sizeof(server));
cout << "bindreturn: " << bindreturn << endl;

不足。在这里您需要再次测试 -1,并打印 WSAGetLastError() 并在得到它时退出。

listen(sock_1,MAX_QUEUE);

未经测试。在这里您需要再次测试 -1 等。

    /* start accepting connection */
    //system("pause");
    sock_2 =accept(sock_1,0,0);
    //system("pause");
    cout << "acceptreturn: " << sock_2 << endl;

再次不足,见上文。

    /* read from sock_2 */
    while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
    {
        if(rec_value<0)
        {
         cout << "error: " << rec_value << endl;
         exit(1);
        }

测试不正确。系统调用通过准确返回 -1 来指示错误,而不仅仅是任何 < 0 的值。例如,由 socket()accept() 返回的套接字 FD 可以为负数,或 -1 以外的任何值。

        else
        {
            cout << "else" << endl;
            send(sock_2,"1,2,3",strlen("1,2,3"),0);
        }
    }
closesocket(sock_1);
closesocket(sock_2);

cout << "End TCP/IP Server" << endl;

return 0;

closesocket() 调用可以明显看出您正在使用 Winsock,在这种情况下 WSAStart()WSACleanup() 不见了。

关于c++ - C++ 中的 TCP/IP 服务器不等待客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34521354/

相关文章:

android inotify_add_watch 失败 : permission denied?

sockets - docker 运行 Jenkins ,套接字连接超时

c - 尝试在关闭旧套接字后使用新套接字,但没有成功

c# - TCP/IP 在不关闭连接的情况下连续接收消息

C#在没有内存不足异常的情况下扫描tcp端口

c - 通过套接字传递字符串数组

c++ - C++中创建线程的基本问题

c++ - 有没有一种方法可以对函数进行模板化,以便可以输入 N 维大括号初始化列表?

c++ - 变量自动分配

javascript - 是否可以在 WebSockets 中使用具有所需端口(例如 6500)的 http 方案而不是 ws 和 wss 方案?