好久好久好久好久没更新了.......由此可推最近好懒啊......
so....整理一下前些日子软件工程学习到的一些东西。
因为是C++写的UI界面和服务器,比HTML和PHP那些自带服务器的困难很多.....而且是第一次编写服务器......
首先,System:String和STL:String之间转换的问题,写个函数就行了。
void MarshalString (String^ s, string& os )
{
const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
之后,就是UI设计让人DT无比的TreeView,就是那种一层一层的树状文件视图。
第一步是先动态更新那棵视图树,于是,单独写个set_tree函数,每次先将树清空,之后再从服务器申请出数据库的数据,重新Add一遍,虽然这样设计对服务器压力很大,但是保持了数据动态更新了。
第二步,就是节点是动态的,而我们希望的是点击叶子节点的时候能够在右边的DataGridView显示出对应的信息......一开始那两个坑货告诉我逐个判断TreeView->SelectedNode->FullPath的值就行了.......感觉好坑爹啊,于是没有着急写,去MSDN查了查TreeView的API,在activity里面给出了详细的点击每有节点后的动作如果实现的代码.......两个坑货有木有......
就是,当你声明一个TreeView的时候,它会对应生成一个监听函数TreeView_AfterSelect(System::Object^ sender, System::Windows::Forms::TreeViewEventArgs^ e),有了这个函数,我们就无敌了.....e->Node->Text我们就能得到这个被点击节点的文本值了,如果不好判定还可以通过e->Node->Parent->Text获得它父亲节点的文本值,如果你这棵树上存在儿子一样爹也一样的子树.....那你也太......
注意一点,parent不一定存在,所以在调用的时候要判断一下非NULL,直接用会出错。
最后,就是关于SOCKET编程问题了,年幼无知啊.....不知道SOCKET这么强大......只要能用01表示的都能传送.....
写个简单的传送任意文件的方式吧,速度不是太快。
服务器端代码,发送文件:
HANDLE fp=CreateFile(L"E://123.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
DWORD fileLen = GetFileSize(fp, &fileLen);
char *buffer = new char[fileLen];
DWORD bufferLen = 0;
ReadFile(fp, buffer, fileLen, &bufferLen, NULL);
bool isFirst = true;
int sendLen = 0;
char sendBuffer[200];
int sendedLen = 0;
int leftLen = fileLen;
char recb[50];
while (1)
{
if (isFirst)
{
sendLen = send(ClientSocket, "~", 1, 0);
isFirst = false;
Sleep(1000);
continue;
}
if ((leftLen <= 0) || (sendedLen >= fileLen))
break;
if (leftLen >= 200)
{
memcpy(sendBuffer, buffer + sendedLen, 200);
sendLen = send(ClientSocket, sendBuffer, 200, 0);
Sleep(1000);
}
else
{
memcpy(sendBuffer, buffer + sendedLen, leftLen);
sendLen = send(ClientSocket, sendBuffer, leftLen, 0);
Sleep(1000);
send(ClientSocket, "#", 1, 0);
}
sendedLen += sendLen;
leftLen = fileLen - sendedLen;
}
客户端代码,接受文件:
int recvLen = 0;
int recvedLen = 0;
DWORD writeLen = 0;
int fileLen = 0;
char *buffer;
char *recvBuffer;
buffer = new char[1024 * 1024 * 10];
recv(*sock, recvBuffer, sizeof(recvBuffer), 0);
if (recvBuffer[0] == '~')
{
memset(recvBuffer, 0, 200);
}
while (1)
{
recv(*sock, recvBuffer, sizeof(recvBuffer), 0);
recvLen = strlen(recvBuffer);
if ((recvLen == 1) && (recvBuffer[0] == '#'))
break;
memcpy(buffer + recvedLen, recvBuffer, recvLen);
recvedLen += recvlen;
}
HANDLE fp = CreateFile(L"F://a.txt",GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(fp, buffer, recvedLen, &writeLen, NULL);
声明,上述代码正确性不保证,仅仅提供参考......因为我的send和rec都是写在一个类里了,当时直接是调用的类函数返回结果.......这里直接用NOTEPAD改的,编译都没编译过.....
再声明,sleep很必要,因为暂停能很好的让消息传递不出现丢失现象(比如服务器端发送消息过快,可能客户端还没有接受完上一个消息,这个消息就发送了,从而丢失了,当然,sleep不是最好的解决方法,最好的是服务器端发送后接收消息,而客户端在接受完发送确认消息,这样就完美了。)