サーバーから1つのスレッドでメッセージを受信するために設定されたマルチスレッドクライアントがあり、他のスレッドはサーバーにメッセージを送信するためにユーザー入力を待ちます。
私はこれが初めてで、私のコードが現在行っていることは次のとおりです。両方のスレッドがサーバーに個別に接続し、サーバーが単一のクライアントを2つのクライアントとして認識しました(両方のスレッドがサーバーに個別に接続されたため)。受信接続と送信接続が同じ接続を利用するようにするにはどうすればよいですか?
クライアントコードの関連部分を含めました(サーバーへの接続は関数 connectToServer を介して行われます)
/*thread for sending messages to server*/
DWORD WINAPI send_handle_thread(LPVOID threadInfo)
{
/*structure contains all the data this callback works on*/
myThreadArgument* send_argument = (myThreadArgument*)threadInfo;
/*get client connection*/
myTcpSocket my_client(PORTNUM);
string server_ip_address = "";
readServerConfig(server_ip_address);
my_client.connectToServer(server_ip_address, ADDRESS); //this is where the thread connects to server
while (1)
{
/*send messages*/
}
return 1;
}
/*thread for receiving messages from server*/
DWORD WINAPI rec_handle_thread(LPVOID threadInfo)
{
/*structure contains all the data this callback works on*/
myThreadArgument* send_argument = (myThreadArgument*)threadInfo;
/*get client connection*/
myTcpSocket my_client(PORTNUM);
string server_ip_address = "";
readServerConfig(server_ip_address);
my_client.connectToServer(server_ip_address, ADDRESS); //this is where thread connects to server
int rec_bytes = 0;
while (1)
{
/*receive messages*/
}
return 1;
}
int main()
{
/*build a semaphore to synchronise access to std::cout*/
mySemaphore cout_semaphore(string(""),1);
/*initialize the winsock library*/
myTcpSocket::initialize();
/*get local (client) information (assume neither the name nor the address is given)*/
myHostInfo client_info;
string client_name = client_info.getHostName();
string client_ip_address = client_info.getHostIPAddress();
cout << "local host (client) information: " << endl;
cout << " name: " << client_name << endl;
cout << " address: " << client_ip_address << endl << endl;
/*retrieve server's IP name and address*/
string server_ip_address = "";
readServerConfig(server_ip_address);
myHostInfo server_info(server_ip_address, ADDRESS);
string server_name = server_info.getHostName();
cout << "remote host (server) information: " << endl;
cout << " name: " << server_name << endl;
cout << " address: " << server_ip_address << endl;
/*retrieve client's IP name and address*/
myTcpSocket my_client(PORTNUM);
cout << my_client;
/*create thread to send messages to server*/
myThreadArgument* send_argument = new myThreadArgument(&my_client, &cout_semaphore, client_name);
myThread* send_thread = new myThread(send_handle_thread, (void*)send_argument);
send_thread->execute();
/*create thread to receive message from server*/
myThreadArgument* rec_argument = new myThreadArgument(&my_client, &cout_semaphore, client_name);
myThread* rec_thread = new myThread(rec_handle_thread, (void*)rec_argument);
rec_thread->execute();
while (1)
{
Sleep(300);
cout << "main thread";
}
return 1;
}
connectToServerコード:
void myTcpSocket::connectToServer(string& serverNameOrAddr,hostType hType)
{
/*
when this method is called, a client socket has been built already,
so we have the socketId and portNumber ready.
a myHostInfo instance is created, no matter how the server's name is
given (such as www.yuchen.net) or the server's address is given (such
as 169.56.32.35), we can use this myHostInfo instance to get the
IP address of the server
*/
myHostInfo serverInfo(serverNameOrAddr,hType);
// Store the IP address and socket port number
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(serverInfo.getHostIPAddress());
serverAddress.sin_port = htons(portNumber);
// Connect to the given address
try
{
if (connect(socketId,(struct sockaddr *)&serverAddress,sizeof(serverAddress)) == -1)
{
#ifdef WINDOWS_7 //XP
int errorCode = 0;
string errorMsg = "error calling connect():\n";
detectErrorConnect(&errorCode,errorMsg);
myException socketConnectException(errorCode,errorMsg);
throw socketConnectException;
#endif
#ifdef UNIX
myException unixSocketConnectException(0,"unix: error calling connect()");
throw unixSocketConnectException;
#endif
}
}
catch(myException& excp)
{
excp.response();
exit(1);
}
}