回答:(因为我无法在 7 小时后回答我的问题:/)好的,我通过这个修改解决了这个问题:
struct RecvDataModel
{
int sockAddr;
string inData; //old: char *inData;
};
void Client::Recv(int sockAddr, char *inData)
{
cout << inData << endl;
RecvDataModel *outData = new RecvDataModel();
outData->sockAddr = sockAddr;
outData->inData = string(inData);//old outData->inData = inData;
pthread_t rThr;
pthread_create(&rThr, NULL, ProcessData, outData);
}
我认为字符串会自动修复 char* 格式,否则我什么都不懂!
现在我想问:字符串和字符的性能是一样的吗?使用字符串而不是char *(指针-void *-除外)有问题吗?
问题:-inData 和 sockAddr 来自一个套接字,这是一个多客户端聊天服务器-在这里,我可以将 sockAddr 发送到 ProcessData 但 inData 无法发送!它随着损坏的格式而改变(比如“testDataTextÿñ€ÿñ:¥øv:Y”我发送了“testDataText”并且它改变了)。我试图创建另一个 char* 并使用 for 循环复制所有内容,但此时如果我发送“te%s;t”之类的数据,则会再次以损坏的格式更改。我能做些什么?
struct RecvDataModel
{
int sockAddr;
char *inData;
};
void *ProcessData(void *arg);
void Client::Recv(int sockAddr, char *inData)
{
RecvDataModel * outData = new RecvDataModel();
outData->sockAddr = sockAddr;
outData->inData = inData;
pthread_t rThr;
pthread_create(&rThr, NULL, ProcessData, outData);
}
void *ProcessData(void *arg)
{
RecvDataModel *inData = (RecvDataModel*)arg;
cout << inData->inData << endl;
return 0;
}
inData 和 sockAddr 来自这里(客户端类):
#include <winsock2.h>
class Client
{
private:
int mySock;
int sockAddr;
bool logged;
void *listen(void)
{
int numBytes;
char buffer[5120];
while(1)
{
numBytes = recv(mySock, buffer, 5120, 0);
if(numBytes == 0 || numBytes == -1)
{
Drop(mySock);
mySock = 0;
sockAddr = 0;
return 0;
}
Recv(sockAddr, buffer);
memset(buffer, 0, sizeof buffer);
}
return 0;
}
public:
void SetSock(int sock)
{
mySock = sock;
}
void SetSockAddr(int addr)
{
sockAddr = addr;
}
void Logged(bool status)
{
logged = status;
}
int GetSock()
{
return mySock;
}
int GetSockAddr()
{
return sockAddr;
}
bool IsLogged()
{
return logged;
}
static void *Listen(void *arg)
{
return ((Client*)arg)->listen();
}
static void Recv(int sockAddr, char *inData);
static void Drop(int sockAddr);
};
和所有 main.cpp
#define PORT 9696
#define MAXCONN 9999
#define BACKLOG 128
#include <winsock2.h>
#include <pthread.h>
#include <iostream>
#include "Client.cpp"
using namespace std;
struct RecvDataModel
{
int sockAddr;
char *inData;
};
Client m_Clients[MAXCONN];
void *AcceptClients(void *arg);
void *HandleClient(void *arg);
void *DropClient(void *arg);
void *ProcessData(void *arg);
void Client::Recv(int sockAddr, char *inData)
{
cout << inData << endl;
RecvDataModel *outData = new RecvDataModel();
outData->sockAddr = sockAddr;
outData->inData = inData;
pthread_t rThr;
pthread_create(&rThr, NULL, ProcessData, outData);
}
void Client::Drop(int sockAddr)
{
pthread_t dThr;
pthread_create(&dThr, NULL, DropClient, (void*)sockAddr);
}
int main()
{
/* WinSock initialization::START */
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
{
cout << "WSA initialization failed!";
WSACleanup();
return 1;
}
/* WinSock initialization::END */
SOCKET m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//--> TCP Socket: socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
//--> UDP Socket: socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
if(m_Socket == INVALID_SOCKET)
{
cout << "Cannot create server socket!";
WSACleanup();
return 1;
}
sockaddr_in m_Inf;
m_Inf.sin_family = AF_INET;
m_Inf.sin_port = htons(PORT);
m_Inf.sin_addr.s_addr = INADDR_ANY;
if(bind(m_Socket, (sockaddr*)(&m_Inf), sizeof(m_Inf)) == SOCKET_ERROR)
{
cout << "Cannot bind server socket!";
WSACleanup();
return 1;
}
if(listen(m_Socket, BACKLOG) == SOCKET_ERROR)
{
cout << "Server socket cannot start listening!";
WSACleanup();
return 1;
}
for(int i = 0; i < MAXCONN; i++)
{
m_Clients[i].SetSock(0);
}
cout << "Listening for connections..." << endl;
pthread_t mThr;
pthread_create(&mThr, NULL, AcceptClients, (void*)m_Socket);
cin.ignore();
cin.get();
cin.clear();
WSACleanup();
return 0;
}
void *AcceptClients(void *arg)
{
int m_Socket = (int)arg;
while(1)
{
sockaddr_in Sin;
int SinLen = sizeof(Sin);
SOCKET c_Socket = accept(m_Socket, (sockaddr*)(&Sin), &SinLen);
if(c_Socket == INVALID_SOCKET)
{
cout << "A connection initialized but dropped! (invalid socket)" << endl;
}
else
{
pthread_t hThr;
pthread_create(&hThr, NULL, HandleClient, (void*)c_Socket);
}
}
return 0;
}
void *HandleClient(void *arg)
{
int inSock = (int)arg;
bool avaibleFound = false;
int lastLooked = 0;
int avaibleAddr = -1;
while(!avaibleFound)
{
avaibleFound = true;
if(lastLooked != MAXCONN)
{
if(m_Clients[lastLooked].GetSock() == 0)
{
avaibleAddr = lastLooked;
avaibleFound = true;
}
else
{
lastLooked += 1;
avaibleFound = false;
}
}
else
{
avaibleAddr = -1;
avaibleFound = true;
}
}
if(avaibleAddr != -1)
{
m_Clients[avaibleAddr].SetSockAddr(avaibleAddr);
m_Clients[avaibleAddr].SetSock(inSock);
cout << "Socket(#" << inSock << ") connected." << endl;
pthread_t cThr;
pthread_create(&cThr, NULL, &Client::Listen, (void*)&m_Clients[avaibleAddr]);
}
else
{
send(inSock, "11", 2, 0);//11: Server is full!
closesocket(inSock);
}
return 0;
}
void *DropClient(void *arg)
{
int inSock = (int)arg;
cout << "Socket(#" << inSock << ") disconnected." << endl;
return 0;
}
void *ProcessData(void *arg)
{
RecvDataModel *inData = (RecvDataModel*)arg;
cout << inData->sockAddr << inData->inData << endl;
delete inData;
return 0;
}
我已经发布了这样的问题,但没有人回答,这对我来说很重要,对不起:L