2013-03-11 52 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