使用TCP套接字进行C ++多客户端聊天

时间:2018-01-25 13:49:56

标签: c++ sockets tcp

我尝试使用TCP套接字在c ++中进行多客户端聊天。 我从this site下载了套接字实现的源代码。

问题是当我尝试从客户端向服务器发送消息时, " ecko"我从服务器上看到的是无穷无尽的空间。

我试图调试客户端代码,客户端正确读取输入。 在前几条消息中,服务器将其消息发送回客户端, 但是在几条消息之后,客户回到了无尽的空间。 我试图使用memset来取消(在所有数组中放零),但是它使情况变得更糟,服务器完全没有收到消息。

非常感谢帮助(:

这是服务器端:

#include "PracticalSocket.h"
#include <stdio.h>
#include <process.h>
#include <Windows.h>
using namespace std;
#pragma comment (lib, "ws2_32.lib")


void ReciveMessages(void * pValue ){
    char recvM[1024];
    TCPSocket* pClient = (TCPSocket*)pValue;
    while(true){
        pClient->recv(recvM,strlen(recvM));
        printf("%s\n",recvM);
    }
}


int main(int argc, char* argv[])
{
    try
    {
        TCPSocket * cClient = new TCPSocket();
        cClient->connect("127.0.0.1",8546);
        _beginthread(ReciveMessages,0,(void*)cClient);
        char st[1024];
        memset(st,0,1024);
        while(true)
        {

            printf("Press Text -->");
            fgets(st, sizeof st, stdin);
            cClient->send(st,strlen(st)+2); 
        }
    }
    catch(...)
    {
        printf("Socket Error..!");
        system("pause");//run cmd comment - stop the system
    }
    return 0;
}

这是客户方:

LocalDateTime

1 个答案:

答案 0 :(得分:0)

代码中有一些错误:

MyClients[ClientCount] = pServerClient;
ClientCount++;

由于上述情况发生在不同的线程中,ClientCount++是非原子的,会导致竞争条件。使ClientCount原子或在一个服务器线程中执行。

在:

Flag = pServerClient->recv(st,strlen(st));
if(Flag>1) {
    printf("%s\n",st);
    for(nI = 0; nI< ClientCount ; nI++)
        MyClients[nI]->send(st,strlen(st)+1);

st并不以\0结尾,因为它可能是部分读取,因此strlen(st)会返回错误的结果。修正:

ssize_t received = pServerClient->recv(st, sizeof st - 1);
if(received > 0) {
    st[received] = 0; // Zero-terminate.        
    printf("%s\n", st);
    for(nI = 0; nI< ClientCount ; nI++)
        MyClients[nI]->send(st, received);

类似问题:

pClient->recv(recvM,strlen(recvM));
printf("%s\n",recvM);

修正:

ssize_t received = pClient->recv(recvM, sizeof recvM - 1);
if(received > 0) {
    recvM[received] = 0;
    printf("%s\n",recvM);
}

并在:

 cClient->send(st,strlen(st)+2); 

发送零终结符没有意义:

 cClient->send(st, strlen(st)); 

TCP是一种流协议,这意味着sendrecv可以发送/接收部分数据,并且没有消息边界。您可能希望delimit your messages