【问题标题】:(WinSocket) Spam on Disconnect(WinSock) 断开连接时的垃圾邮件
【发布时间】:2013-02-21 19:32:30
【问题描述】:

我正在尝试为客户端/服务器聊天程序编写服务器。 唯一的问题是,一旦客户端断开连接,服务器就会开始向服务器发送他们的最后一条消息。即使他们重新连接,它也会不断发送垃圾邮件。我试过谷歌搜索,但找不到任何东西。 这是服务器代码:

#include "MasterServer.h"
using namespace std;
SOCKADDR_IN Server;
int addrlen = sizeof(Server);
SOCKET sListen;
SOCKET Connect; 
SOCKET* Connections;
int port = 444;
int ConCounter = 0;
char* Recv = new char[256];
int ServerThread(int ID)
{

ZeroMemory(Recv, sizeof(Recv));
for(;;)
{
    if(recv(Connections[ID],Recv ,256 ,NULL))
    {
        cout << Recv << endl;
    }
}
}

int InitWinSock()
{
int RetVal = 0;
      WSAData wsa;
      WORD Version = MAKEWORD(2,1);
      RetVal = WSAStartup(Version, &wsa);

      return RetVal;
}


int main()
{
    int RetVal = 0;
    RetVal = InitWinSock();
    if(RetVal != 0)
    {
        cout << "WinSock Start Up Failure";
    }
      Connections = (SOCKET*)calloc(64, sizeof(SOCKET));

       sListen = socket(AF_INET, SOCK_STREAM, NULL);
       Connect = socket(AF_INET, SOCK_STREAM, NULL);
       cout << "\t\t----====ModernBacon Server====----"<< endl;

        cout << "What Port Would You Like To Run On [Default 444]: ";
        cin >> port;

        system("cls");
      Server.sin_addr.s_addr = inet_addr("127.0.0.1");
      Server.sin_family = AF_INET;
      Server.sin_port = htons(port);

      bind(sListen, (SOCKADDR*)&Server, sizeof(Server));
      //Listening
      listen(sListen, 64);
cout << "Listening For Connections IP:"<<inet_ntoa(Server.sin_addr);"Port:"<<port<< 
endl;


      for(;;)
          {
            if(Connect = accept(sListen, (SOCKADDR*)&Server, &addrlen))
            {
                Connections[ConCounter] = Connect;
                char* ID = new char[64];
                ZeroMemory(ID, sizeof(ID));
                itoa(ConCounter, ID, 10);
                send(Connections[ConCounter], ID, sizeof(ID),NULL);

                ConCounter = ConCounter + 1;
                CreateThread(NULL,NULL, (LPTHREAD_START_ROUTINE) 
ServerThread, (LPVOID)(ConCounter -1), NULL, NULL);

                cout << "\t\tClient Connected!\tID: " <<
ConCounter << endl;



            }

      }
      return(0);
}

我不知道发生了什么事......

【问题讨论】:

  • 你知道recv在出错时返回什么吗?
  • 当客户端断开分配给他们的线程时,它永远不会消失。当一个新的客户端被分配给该连接 ID 时,会发生什么?此外,所有线程共享 same 缓冲区以从套接字读取。这是另一场灾难。
  • 垃圾邮件是发送垃圾邮件的行为。这里没有电子邮件代码。在这种情况下,您所说的“垃圾邮件”到底是什么意思?
  • @EJP 垃圾邮件在此处的正确上下文中使用。垃圾邮件是在 Internet 上不加选择地向(大量收件人)发送相同的消息。他的意思是消息被一遍又一遍地重新发送。

标签: c++ sockets chat


【解决方案1】:

您的代码存在很多问题。尝试更多类似的方法:

#include "MasterServer.h"
#include <string>

using namespace std;

static const int MAX_CLIENTS = 64;
static const int MAX_RECV = 256;

struct ClientInfo
{
    int ID;
    SOCKET Connection;
    char Recv[MAX_RECV];
};

ClientInfo Clients[MAX_CLIENTS];

DWORD WINAPI ServerThread(LPVOID lpParam)
{
    ClientInfo *Client = (ClientInfo*) lpParam;
    char szID[64] = {0};

    itoa(Client->ID, szID, 10);

    int RetVal = send(Client->Connection, szID, sizeof(szID), NULL);
    if (RetVal != sizeof(szID))
    {
        cout << "Client " << Client->ID << " Send Failure. Error " << WSAGetLastError() << endl;
    }
    else
    {
        do
        {
            RetVal = recv(Client->Connection, Client->Recv, MAX_RECV, NULL);
            if (RetVal == SOCKET_ERROR)
            {
                cout << "Client " << Client->ID << " Recv Failure. Error " << WSAGetLastError() << endl;
                break;
            }

            if (RetVal == 0)
            {
                cout << "Client " << Client->ID << " disconnected" << endl;
                break;
            }

            cout << "Client " << Client->ID << ": " << string(Client->Recv, RetVal) << endl;
        }
        while (true);
    }

    closesocket(Client->Connection);
    Client->Connection = INVALID_SOCKET;

    return 0;
}

int InitWinSock()
{
    WSAData wsa;
    return WSAStartup(MAKEWORD(2,1), &wsa);
}

int main()
{
    SOCKADDR_IN addr;
    int addrlen;
    SOCKET sListen;
    SOCKET sClient;
    int port = 444;
    int index;

    cout << "\t\t----====ModernBacon Server====----"<< endl;

    for (int i = 0; i < MAX_CLIENTS; ++i)
        Connections[i] = INVALID_SOCKET;

    int RetVal = InitWinSock();
    if (RetVal != 0)
    {
        cout << "WinSock Start Up Failure. Error " << RetVal << endl;
        return 0;
    }

    sListen = socket(AF_INET, SOCK_STREAM, NULL);
    if (sListen == INVALID_SOCKET)
    {
        cout << "WinSock Socket Failure. Error " << WSAGetLastError() << endl;
        return 0;
    }

    cout << "What Port Would You Like To Run On [Default 444]: ";
    cin >> port;
    system("cls");

    ZeroMemory(&addr, sizeof(addr));
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    RetVal = bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
    if (RetVal != 0)
    {
        cout << "WinSock Bind Failure. Error " << WSAGetLastError() << endl;
        return 0;
    }

    //Listening
    RetVal = listen(sListen, MAX_CLIENTS);
    if (RetVal != 0)
    {
        cout << "WinSock Listen Failure. Error " << WSAGetLastError() << endl;
        return 0;
    }

    cout << "Listening For Connections. IP: " << inet_ntoa(addr.sin_addr) << ", Port: " << port << endl;

    do
    {
        addrlen = sizeof(addr);
        sClient = accept(sListen, (SOCKADDR*)&addr, &addrlen);
        if (sClient == INVALID_SOCKET)
        {
            cout << "WinSock Accept Failure. Error " << WSAGetLastError() << endl;
            return 0;
        }

        index = -1;
        for (int i = 0; i < MAX_CLIENTS; ++i)
        {
            if (Clients[i].Connection == INVALID_SOCKET)
            {
                 index = i;
                 break;
            }
        }

        if (index == -1)
        {
            closesocket(sClient);
            cout << "\t\tClient Connected. Max Clients Exceeded!" << endl;
            continue;
        }

        Clients[index].ID = index + 1;
        Clients[index].Connection = sClient;

        CreateThread(NULL, NULL, &ServerThread, &Clients[index], NULL, NULL);

        cout << "\t\tClient Connected!\tID: " << Clients[index].ID << endl;
    }
    while (true);

    return 0;
}

【讨论】:

    猜你喜欢
    • 2022-06-14
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2014-05-19
    • 2013-05-19
    • 2011-01-24
    相关资源
    最近更新 更多