回答:(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* 形式を修正すると思います。そうしないと何も理解できません!
そして今、私は聞きたいです: string と char のパフォーマンスは同じですか? char* の代わりに文字列を使用することに問題はありますか (pointers-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