how can client retrieve vector list from server?

Jun 13, 2013 at 1:11pm
i have a client application that needs to connect to servers from anywhere so to do this i'm trying to create a master server. this master server saves the other servers ip addresses in a vector. the client will then get this list of servers and select one to connect to. so basically the master server just needs to pass on the servers addresses to the client when the client connects

i need my client application to access this vector list from the master server and display the addresses in a listbox

so how can the client access the vector list from the master server?

here is the code from the master server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
WSADATA wsaData; 
SOCKET ListeningSocket, NewConnection; 
SOCKADDR_IN ServerAddr, SenderInfo;  quantity
int Port = 7171;
char recvbuff[1024];
int ByteReceived, i, nlen;

ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

ServerAddr.sin_family = AF_INET; 
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);

std::vector<std::string> vClientIPs; // client ip string vector
while(1)
{
    NewConnection = SOCKET_ERROR;
    while(NewConnection == SOCKET_ERROR)
    {
        NewConnection = accept(ListeningSocket, NULL, NULL);
        printf("Server: New client got connected, ready to receive and send data...\n\n");
        ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);

        if ( ByteReceived > 0 )
        {
            getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
            printf("Server: IP(s) used by Server: %s\n", inet_ntoa(ServerAddr.sin_addr)); 
            vClientIPs.push_back(std::string(inet_ntoa(ServerAddr.sin_addr))); //insert client ip
//need to send vector to client
            printf("Server: port used by Server: %d\n\n", htons(ServerAddr.sin_port));
            memset(&SenderInfo, 0, sizeof(SenderInfo));
            nlen = sizeof(SenderInfo);
            getpeername(NewConnection, (SOCKADDR *)&SenderInfo, &nlen);
            printf("Server: IP used by Client: %s\n", inet_ntoa(SenderInfo.sin_addr));
            printf("Server: Port used by Client: %d\n", htons(SenderInfo.sin_port));
            printf("Server: Bytes received: %d\n", ByteReceived);
            printf("Server: Message from client: \"");

            for(i=0;i < ByteReceived;i++)
            {
                printf("%c", recvbuff[i]);
            }
            printf("\"");
            }
            else if ( ByteReceived == 0 )
            {
                printf("Server: Connection closed!\n");
            }
            else
            {
                printf("Server: recv failed with error code: %d\n", WSAGetLastError());
            }
        }
    }
}


here is the client code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
WSADATA wsaData;
SOCKET SendingSocket;
SOCKADDR_IN ServerAddr, ThisSenderInfo;
unsigned int Port = 7171;
int RetCode;

char sendbuf[1024] = "This is a test string from client";
int BytesSent, nlen;

WSAStartup(MAKEWORD(2,2), &wsaData);
SendingSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 

ClientInfo info;
//need to display vector list not current server's address
info.addr = inet_ntoa(ServerAddr.sin_addr); //push address onto listbox

RetCode = connect(SendingSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));
getsockname(SendingSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));

BytesSent = send(SendingSocket, sendbuf, strlen(sendbuf), 0);

if(BytesSent == SOCKET_ERROR)
{
    AfxMessageBox("Send error %ld.\n", WSAGetLastError());
}
else
{
    memset(&ThisSenderInfo, 0, sizeof(ThisSenderInfo));
    nlen = sizeof(ThisSenderInfo);

    getsockname(SendingSocket, (SOCKADDR *)&ThisSenderInfo, &nlen);         

}

Mutex<CriticalSection>::Lock lock(client_cs);
clients.push_back(info);

right now the client just connects to a server which is on the local machine and it only displays one address (the one i send it to). how can i get the address saved in the vector and display that instead?
Last edited on Jun 13, 2013 at 1:32pm
Jun 13, 2013 at 1:16pm
Use some protocol of your choice, for example:
send first the total size of all entries
begin send each entry separated by newline

So the client knows when the transmission ends and parses the results. This is one suggestion, you could make it whatever you seem fit for you.
Jun 13, 2013 at 1:18pm
but what would the code for sending and receiving be?
i know the send function is send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
(and the same for receive but with recv instead of send)

but how do i set the vector data to be sent/received?
Last edited on Jun 13, 2013 at 1:43pm
Jun 13, 2013 at 2:07pm
Iterate through each element of the vector using a loop and send the data multiple times, as you do now (you said now send only one element).

Or you could append the data to a buffer and send once, it's your choice how you do it. Beware of the strlen() if the data ontains NUL characters.
Last edited on Jun 13, 2013 at 2:08pm
Jun 13, 2013 at 2:41pm
but how do i set the vector data to be sent/received?

if i try using vClientIPs = send( ListeningSocket, recvbuff, (int)strlen(recvbuff), 0 );
i get an error
Last edited on Jun 13, 2013 at 2:41pm
Jun 13, 2013 at 3:50pm
1
2
3
4
5
6
7
8
std::string recvbuf;

for (size_t i = 0; i < vectorBuf.size(); i++) {
recvbuf += vectorBuf[i];
recvbuf += "\r\n";
}

recvBuf += "\r\n";


Then send data as usual with:
vClientIPs = send( ListeningSocket, recvBuf.c_str(), (int)recvBuf.size(), 0 );

To receive just keep looking for an empty newline "\r\n\r\n" which signals end of file in this example.
Last edited on Jun 13, 2013 at 3:52pm
Topic archived. No new replies allowed.