Click to See Complete Forum and Search --> : winsock string question


Organize
June 2nd, 2004, 10:50 AM
Hello
I am trying to make a winsock based client-server applications that allows the client to view the files on the HDD of the server.
For this I need to send the tree from the server to the client, so I do like this:



void BrowseFolder(SOCKET client, char *path)
{
CFileFind f,
g;
BOOL ok,
bWorking;
char msg[1000];
int len;

ok = f.FindFile(path, 0);

if(ok)
{
f.FindNextFile();
if( f.IsDirectory() ) // item is a directory and we will show all the items from within it
{
strcpy(msg, "ReceiveFiles");
send(client, msg, strlen(msg), 0);
f.Close();
strcat(path, "\\*.*");
bWorking = g.FindFile(path, 0);
while(bWorking)
{
bWorking = g.FindNextFile();
memset(msg, 0, 100 );
strcpy( msg, (LPCTSTR)g.GetFileName());
msg[strlen(msg)]='\0';
len = strlen(msg);
send(client, msg, len, 0);
}
}
else
{
//bla bla bla
}
}
else
{
// we get her4e if the file is not found
MessageBox(0, "Fisierul nu exista", "Eroare in lista", MB_OK);
}
f.Close();
}



and then on the client side:



HTREEITEM hItem = m_tree.GetSelectedItem();
char path[1000]="",
buf[1000],
mode[100];
int n;

if(hItem==NULL)
{
MessageBox("No item selected","Warning", MB_OK|MB_ICONINFORMATION);
return;
}

GetCurrSelItemPath(path, hItem, 0);

strcpy(buf, "browse ");
strcat(buf, path);
send( conn , buf, strlen(buf), 0);
memset(mode, 0, strlen(buf));
n = recv(conn, mode, 100, 0);
if(n==SOCKET_ERROR)
{
MessageBox("Error","s");
return;
}
mode[n]=/*'\0'*/0;
if(strcmp(mode, "ReceiveFiles")==0)
{
while(true)
{
memset(buf, 0, strlen(buf));
n = recv( conn, buf, 512, 0);
if(n==SOCKET_ERROR)
{
break;
}
buf[n]=/*'\0'*/0;
MessageBox( buf, "Fisiere");
}

}

now I went over both client and server and the server is sending the information right, that is it is sending every item(file or folder) one at a time to the client, but when the client receives them all the items are in a string like this "RecieveFiles...SoftwareUTIL" when I browse my folder Chip wich contains the subfolders Software and Util and because of this (probably) the program blocks also., I would like the client to recieve the item strings like this "Software" and "UTIL".Understand?
Please help

If you don't understand could you please at least direct me to a sample that attempts to achieve what I am trying to achieve.

kuphryn
June 2nd, 2004, 12:02 PM
The client received whatever was sent on the server-side. Design a protocol between the two sides. If you send "abc...xyz," then the client will receive that exact string asynchronically.

Kuphryn

Andreas Masur
June 3rd, 2004, 05:39 AM
[Moved thread]

VipulPathak
June 3rd, 2004, 06:58 AM
Originally posted by Organize

Now I went over both client and server and the server is sending the
information right, that is it is sending every item(file or folder) one at
a time to the client, but when the client receives them all the items
are in a string like this "RecieveFiles...SoftwareUTIL" when I browse
my folder Chip wich contains the subfolders Software and Util and because
of this (probably) the program blocks also., I would like the client to
recieve the item strings like this "Software" and "UTIL". Understand?


You can try this:
From Server send information separated with a special character and at client end when you receive the String chunk, parse it.

For example:

const int MAXSIZEBUF = 8188 ; // OR Any thing else
struct ServerDirStruct
{
unsigned long ulLengthOfFollowingData ;
char szHierarchy[MAXSIZEBUF] ;
} X ;
// ... ... ...
// ... ... ...
// ... ... ...
StringCchPrintfEx(X.szHierarchy, MAXSIZEBUF, 0, 0,
STRSAFE_NULL_ON_FAILURE, "%s#%s#%s",
"Software", "Utils", "AnotherSubFolder") ; // Etc.
// ... ... ...
// ... ... ...
X.ulLengthOfFollowingData = strlen(X.szHierarchy) ;
int nLengthSendable = sizeof(long) + X.ulLengthOfFollowingData ;
send(skConnectedClient, (LPSTR) &X, nLengthSendable, 0) ;



So this way, the data Transferred will be <31>"Software#Utils#AnotherSubFolder" ... // here <31> is the 4 byte DWORD travelling through Socket

At Client End, read 4 bytes first, cast it to an unsigned long. This will tell you exactly how much bytes are ready to be read. Read that much bytes and store them in a std::string object. Use the find() and substr() methods to extract individual parts of the String.

Since TCP/IP is a stream based protocol, when you send data with multiple send(), it is normal if you receive it in once, and even one send can also result in multiple smaller recv().

Hope this will Help.

Regards.

-Vipul Pathak ;