套接字不发送数据

时间:2019-06-08 23:06:01

标签: c++ sockets

我目前正在使用一个即时消息传递系统,该系统需要服务器和客户端之间进行通信。 我在C ++中使用默认套接字API进行了尝试。 问题是,即使两个程序(服务器和客户端)都可以正常编译,也不会从客户端发送任何套接字到达服务器。

我不知道我在这里做错了什么(我遍历了5次代码,甚至从头开始做了一次,没有成功)。 我使用“调试”消息来定位问题,它们都与我使用的处理循环有关。


// code from the server

#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <thread>
#include <vector>
#include <Ws2tcpip.h>
#include <string>

int main()
{
    std::locale::global(std::locale("fr-FR"));

    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 
    {
        std::cout << "Error initializing winsock";
        return -1;
    }

    SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (server == INVALID_SOCKET)
    {
        std::cout << "Error initializing the socket ";
        return -2;
    }

    const unsigned short port = 9999;
    sockaddr_in addr;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port); 
    addr.sin_family = AF_INET; 

    int res = bind(server, (sockaddr*)&addr, sizeof(addr));
    if (res != 0)
    {
        std::cout << "Error when binding";
        return -3;
    }

    res = listen(server, SOMAXCONN);
    if (res != 0)
    {
        std::cout << "Error on calling listen";
        return -4;
    }

    std::cout << "Server successfully launched" << std::endl;

    char buffer[1025];

    while (true)
    {
        sockaddr_in from = { 0 };
        int addrlen = sizeof(from);
        SOCKET newClient = accept(server, (SOCKADDR*)(&from), &addrlen);

        if (newClient != SOCKET_ERROR) 
        {
            std::cout << "Client connected successfully" << std::endl;

            int Bytes = recv(newClient, buffer, 1024, 0);

            if (Bytes <= 0)
            {
                break;
            }

            std::cout << "Message received from client : " << buffer << std::endl;
            send(newClient, buffer, 1024, 0); // send it back to client
        }
    }
    return 0;
}


// code from the client 

#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <thread>
#include <vector>
#include <Ws2tcpip.h>
#include <string>

#define _WINSOCK_DEPRECATED_NO_WARNINGS

void sendMessage(SOCKET s);
void recvMessage(SOCKET s);

int main()
{
    std::locale::global(std::locale("fr-FR"));

    WSAData wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) 
    {
        std::cout << "Error initializing winsock";
        return -1;
    }

    SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server == INVALID_SOCKET)
    {
        std::cout << "Error initializing the socket ";
        return -2;
    }

    sockaddr_in addr;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);

    int res = bind(server, (sockaddr*)&addr, sizeof(addr));
    if (res != 0)
    {
        std::cout << "Error when binding";
        return -3;
    }

    if (connect(server, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
        std::cout << "Erreur when connecting : " << WSAGetLastError() << std::endl;
        return -4;
    }

    std::cout << "You are connected to server" << std::endl;

    std::thread sending(sendMessage, server);
    std::thread receiving(recvMessage, server);

    sending.detach();
    receiving.detach();

    while (true)
    { }

    return 0;
}


void sendMessage(SOCKET s)
{
    while (true)
    {
        std::string buff;
        std::cout << "Type your message :" << std::endl;
        std::getline(std::cin, buff);
        std::cout << std::endl;

        int Bytes = send(s, buff.c_str(), 1024, 0);
        if (Bytes <= 0)
        {
            break;
        }
    }
}

void recvMessage(SOCKET s)
{
    while (true)
    {
        char buffer[1025];
        int Bytes = recv(s, buffer, 1024, 0);
        if (Bytes <= 0)
        {
            break;
        }

        std::cout << "The server sent : " << buffer << std::endl;
    }
}

启动客户端时,服务器应显示客户端已连接的消息并显示chat命令,但服务器控制台中唯一显示的消息是服务器已正确启动...但是客户端显示应该由服务器“接收”的消息。

PS:我知道代码不需要那么多的“ include”语句,只是我不记得哪个包含哪些函数,所以我想为那些想要编译该函数的人提供足够的内容代码。

1 个答案:

答案 0 :(得分:1)

几件事:

首先,这是错误的:

send(s, buff.c_str(), 1024, 0)

您基本上是在告诉send它要寻址的缓冲区是完整的1kb,然后将其全部发送出去。尚不知道实际上有多少内存有效,并且对终止的字符串一无所知。

第二,客户端设置错误。不要bind到客户端套接字; connect就足够了。注意这些:

int res = bind(server, (sockaddr*)&addr, sizeof(addr));
if (res != 0)
{
    std::cout << "Error when binding";
    return -3;
}

if (connect(server, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{
    std::cout << "Erreur when connecting : " << WSAGetLastError() << std::endl;
    return -4;
}

该绑定不应该存在。如果可以建立连接,connect将绑定到套接字。删除客户端的绑定部分,更正缓冲区管理的正确性,并将closesocket调用放在它们所属的位置,您的程序将在功能上走得更远。仍然存在一些问题逻辑工作流,但是至少可以更好地建立连接。