杂记 of 软件工程

好久好久好久好久没更新了.......由此可推最近好懒啊......


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不是最好的解决方法,最好的是服务器端发送后接收消息,而客户端在接受完发送确认消息,这样就完美了。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值