2013-02-21 47 views
0

我有一個服務器多客戶端程序。服務器需要(也可以)隨時向客戶端發送消息,因此客戶端需要不斷準備好接收(並在控制檯上顯示)服務器發送的所有消息。客戶端控制檯顯示收到的消息並接受消息

與此同時,客戶端控制檯需要接受要發送到服務器進行處理的輸入(服務器充當客戶端之間的中介)。

我該怎麼做?我正在處理從http://www.codeproject.com/Articles/7785/Single-Server-With-Multiple-Clients-a-Simple-C-Imp取得的一段代碼,客戶端代碼(我將在下面附上)通過接受來自服務器的消息,在將消息發送到服務器之前準備好接收消息。我如何適應這個做我所需要的?

我只包括客戶端代碼的主體,因爲我認爲它可能只是使用循環的問題 - 儘管我無法確定什麼循環 - 所以請讓我知道是否應該附加任何其他代碼。

#include "stdafx.h" 
#include "mySocket.h" 
#include "myLog.h" 
#include "myException.h" 
#include "myHostInfo.h" 

myLog winLog; 
void readServerConfig(string&); 
void checkFileExistence(const string&); 

int main() 
{ 
//initialize the winsock library 
myTcpSocket::initialize(); 

//get client's information (assume neither the name nor the address is given) 
winLog << endl; 
winLog << "retrieve the localHost [CLIENT] name and address:" << endl; 
myHostInfo clientInfo; 
string clientName = clientInfo.getHostName(); 
string clientIPAddress = clientInfo.getHostIPAddress(); 
cout << "name: " << clientName << endl; 
cout << "address: " << clientIPAddress << endl; 
winLog << "  ==> name: " << clientName << endl; 
winLog << "  ==> address: " << clientIPAddress << endl; 

//get server's IP address and name 
string serverIPAddress = ""; 
readServerConfig(serverIPAddress); 
winLog << endl; 
winLog << "retrieve the remoteHost [SERVER] name and address:" << endl; 
winLog << "  ==> the given address is " << serverIPAddress << endl; 

myHostInfo serverInfo(serverIPAddress,ADDRESS); 
string serverName = serverInfo.getHostName(); 
cout << "name: " << serverName << endl; 
cout << "address: " << serverIPAddress << endl; 
winLog << "  ==> name: " << serverName << endl; 
winLog << "  ==> address: " << serverIPAddress << endl; 

//create the socket for client 
myTcpSocket myClient(PORTNUM); 
cout << myClient; 
winLog << "client configuation: " << endl; 
winLog << myClient; 

// connect to the server. 
cout << "connecting to the server [" << serverName << "] ... " << endl; 
winLog << "connecting to the server [" << serverName << "] ... " << endl; 
myClient.connectToServer(serverIPAddress, ADDRESS); 

int recvBytes = 0; 
while (1) 
{ 
    // send message to server 
    char messageToServer[MAX_MSG_LEN+1]; 
    memset(messageToServer, 0, sizeof(messageToServer)); 
    cout << "[SEND] "; 
    cin.getline(messageToServer,MAX_MSG_LEN); 

    winLog << "[SEND] " << messageToServer << endl; 
    myClient.sendMessage(string(messageToServer)); 

    if (!string(messageToServer).compare("Quit") || !string(messageToServer).compare("quit")) 
     break; 

    // receive message from server 
/* string messageFromServer = ""; 
    recvBytes = myClient.receiveMessage(messageFromServer); 
    if (recvBytes == -99) break; 

    cout << "[RECV:" << serverName << "]: " << messageFromServer << endl; 
    winLog << "[RECV:" << serverName << "]: " << messageFromServer << endl;*/ 

} 

return 1; 

}

回答

0

如果你熟悉線程編程,我建議分配一個單獨的線程來處理傳入流量,另一個處理傳出的流量。

另一種選擇是使用異步套接字。

0

1.After客戶端連接到服務器client1client2client3不要關閉連接並等待read()

2.1936服務器端,您可能想看看pselect&timeout

3.After的連接是由商店session_fd的進入和陣列clientId[3]

4.Now你可以寫上write(client[0-2], , ...)

LOGIC--

int socks[10] = {... some client sockets...} 

while(1) 
{ 
    fd_set readSet, writeSet; 
    FD_ZERO(&readSet); 
    FD_ZERO(&writeSet); 

    int maxSock = -1; 
    for (int i=0; i<10; i++) 
    { 
    FD_SET(socks[i], &readSet); 
    if (socks[i] > maxSock) maxSock = socks[i]; 

    if (IHaveDataToSendToThisSocket(i)) // implement this function as appropriate to your program 
     { 
     FD_SET(socks[i], &writeSet); 
     if (socks[i] > maxSock) maxSock = socks[i]; 
     } 
} 

int ret = select(maxSock+1, &readSet, &writeSet, NULL, NULL); 
if (ret < 0) 
{ 
    perror("select() failed"); 
    break; 
} 

// Do I/O for sockets that are ready 
for (int i=0; i<10; i++) 
{ 
    if (FD_ISSET(socks[i], &readSet)) 
    { 
    // there is data to read on this socket, so call recv() on it 
    } 

    if (FD_ISSET(socks[i], &writeSet)) 
    { 
    // this socket has space available to write data to, so call send() on it 
    } 
} 
} 
+0

代碼片段通過@Jeremy Friesner: :http://stackoverflow.com/questions/8674491/server-with-multiple-clients-writing-with-select – 2014-01-23 08:38:31