2013-03-11 53 views
0

我有一個多線程的客戶即將成立,以從服務器一個線程收到消息,而爲了其他線程等待用戶輸入發送向服務器發送消息。如何訪問同一個插座上的多個線程的多線程客戶端

我是新來這個,什麼我的代碼目前所做的是:這兩個線程將單獨連接到服務器,這使得服務器識別單個客戶端爲兩個客戶端(因爲連接到服務器單獨兩個線程)。我如何解決這個問題,以便接收和發送連接將使用相同的連接?

我已經包括了我的客戶端代碼相關部分(連接到服務器是通過函數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); 
} 
} 

回答

1

只要使用相同插座FD在兩個地方。使用時甚至不需要同步。

+0

我該怎麼做呢? – sccs 2013-03-11 05:36:48

+0

我不明白這個問題。你在問什麼?如何在一個程序的兩個部分同時使用一個變量? – EJP 2013-03-11 05:48:40

+0

對不起 - 我的意思是我該如何實現呢?我以某種方式替換其中一個線程上的connectToServer嗎? – sccs 2013-03-11 06:12:00