| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1168 人关注过本帖
标题:C++Builder使用技巧集再续
只看楼主 加入收藏
pineyer
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2004-4-23
收藏
 问题点数:0 回复次数:1 
C++Builder使用技巧集再续

TCP/IP头格式

一、先是常用的IP头格式。 IP头格式: 版本号 (4位) IP头长度 (4位) 服务类型 (8位) 数据包长度 (16位) 标识段 (16位) 标志段 (16位) 生存时间 (8位) 传输协议 (8位) 头校验和 (16位) 发送地址 (16位) 目标地址 (16位) 选项 填充

简单说明 ============ 1. IP头长度计算所用单位为32位字, 常用来计算数据开始偏移量 2. 数据包长度用字节表示, 包括头的长度, 因此最大长度为65535字节 3. 生存时间表示数据被丢失前保存在网络上的时间, 以秒计. 4. 头校验和的算法为取所有16位字的16位和的补码. 5. 选项长度是可变的, 填充区域随选项长度变化, 用于确保长度为整字节的倍数.

描述 ============ struct iphdr { BYTE versionihl; BYTE tos; WORD tot_len; WORD id; WORD frag_off; BYTE ttl; BYTE protocol; WORD check; DWORD saddr; DWORD daddr; /* Put options here. */ };

二、TCP头格式 TCP头格式: 源端口 (16位) 目的端口 (16位) 序号 (32位) 确认号 (32位) 数据偏移 (4位) 保留 (6位) 标志 (6位) 窗口 (16位) 校验和 (16位) 紧急指针 (16位) 选项 填充

简单说明 ============ 1. 数据偏移用于标识数据段的开始 2. 保留段6位必须为0 3. 标志包括紧急标志、确认标志、入栈标志、重置标志、同步标志等。 4. 校验和计算方式为将头与16位二进制反码和中的16位二进制反码加在一起。 5. 选项长度是可变的, 填充区域随选项长度变化, 用于确保长度为整字节的倍数. 6. 更详细的说明请参阅有关资料。

描述 ============ struct tcphdr { WORD SourPort; WORD DestPort; DWORD SeqNo; DWORD AckNo; BYTE HLen; BYTE Flag; WORD Window; WORD ChkSum; WORD UrgPtr; /* Put options here. */ };

UDP

一、说明 使用UDP时,直接使用API代替控件。

第一个程序(ReadBufferUdp)使用来接收到缓存中。

"Destino"变量非常重要,如果你从其他地方接收数据到Buffer,你必须设置Destino = 0 并且在以后执行的时候赋值你将要发送的包的地址给它(after the execution it will have the address which send you the packet.)。 如果你只想从一个指定的地址接收数据,你必须设置变量Destino = <address>.

"gvEncerrar" 用来中止处理过程。(gvEncerrar被设置为全局变量。)

超时时间设置。"Inicio + 12" = 12 sec of timeout.

第三个程序是用来准备WinSock程序。

二、代码

int ReadBufferUdp(unsigned long *Destino,void *T,int Size) { char Buffer[128]; SOCKADDR_IN SockAddr; int LenSockAddr=sizeof(SOCKADDR_IN); fd_set FdRead; struct timeval t_val; int Ret; time_t Inicio = time(NULL);

Application->ProcessMessages(); if(gvEncerrar) return false;

FD_ZERO(&FdRead); FD_SET(gvSocket,&FdRead); t_val.tv_sec=0; t_val.tv_usec=0;

while((Ret=select(0,&FdRead,NULL,NULL,&t_val))!=1 && (Inicio + 12) > time(NULL) && !gvEncerrar) { FD_ZERO(&FdRead); FD_SET(gvSocket,&FdRead); t_val.tv_sec=0; t_val.tv_usec=0; Application->ProcessMessages(); } if(Ret != 1) return false;

if(recvfrom(gvSocket,Buffer,Size,0,(LPSOCKADDR)&SockAddr,&LenSockAddr)!=Size)

return false;

if(*Destino == 0) { *Destino = SockAddr.sin_addr.s_addr; } else if(*Destino != SockAddr.sin_addr.s_addr) return false;

memcpy(T,Buffer,Size); return true; }

int WriteBufferUdp(unsigned long Destino,void *T,int Size) { SOCKADDR_IN SockAddr; int Sent;

Application->ProcessMessages(); SockAddr.sin_family = AF_INET; SockAddr.sin_port = gvPortUdp; SockAddr.sin_addr.s_addr = Destino; Sent = sendto(gvSocket,(char *)T,Size,0,(LPSOCKADDR)&SockAddr,sizeof(SockAddr)); if(Sent != Size) return false; else return true; }

void InicializaTCPIP() {

WORD wVersionRequested; WSADATA wsaData; IN_ADDR In; PSERVENT PServent; SOCKADDR_IN SockAddrIn; wVersionRequested = MAKEWORD( 1, 1 );

if(WSAStartup( wVersionRequested, &wsaData )) { ShowMessage("Erro na inicializao do TCP/IP"); Application->Terminate(); return; }

// Get the port on service file if((PServent=getservbyname("your_service_name","udp"))==NULL) { ShowMessage("Erro obtendo port do servi transurb/udp"); Application->Terminate(); return; } gvPortUdp = PServent->s_port; sprintf(StrAux,"Servi transurb/udp port:%d",ntohs(gvPortUdp)); Log(StrAux);

// Open de Socket if((gvSocket = socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET) { ShowMessage("Erro na criao do socket"); Application->Terminate(); return; } Log("Socket criado com sucesso");

// Do the bind SockAddrIn.sin_family = AF_INET; SockAddrIn.sin_port = gvPortUdp; SockAddrIn.sin_addr.s_addr = NULL;

if(bind(gvSocket,(LPSOCKADDR)&SockAddrIn,sizeof(SockAddrIn))==SOCKET_ERROR)

{ ShowMessage("Erro no bind do socket"); Application->Terminate(); return; } Log("Bind do socket com sucesso");

}

判断windows的Desktop及其它目录

使用API函数SHGetSpecialFolder。shlobj.h里有SHGetSpecialFolder的原型声明。这个函数可以帮我们找到windows的Desktop目录、启动目录、我的文档目录等。

SHGetSpecialFolder需要三个参数。 第一个参数是HWND,它指定了"所有者窗口":在调用这个函数时可能出现的对话框或消息框。第二个参数是一个整数id,决定哪个目录是待查找目录,它的取值可能是:

CSIDL_BITBUCKET 回收站 CSIDL_CONTROLS 控制面板 CSIDL_DESKTOP Windows 桌面desktop CSIDL_DESKTOPDIRECTORY desktop的目录 CSIDL_DRIVES 我的电脑 CSIDL_FONTS 字体目录 CSIDL_NETHOOD 网上邻居 CSIDL_NETWORK 网上邻居virtual folder CSIDL_PERSONAL 我的文档 CSIDL_PRINTERS 打印机 CSIDL_PROGRAMS 程序组 CSIDL_RECENT 大多数最近打开的文档列一 CSIDL_SENDTO “发送到”菜单项 CSIDL_STARTMENU 任务条启动菜单项 CSIDL_STARTUP 启动目录 CSIDL_TEMPLATES 临时文档 最后一个参数是pidl地址。SHGetSpecialFolderLocation把地址写到pidl。

下面的代码演示了怎样使用SHGetSpecialFolderLocation:

//---------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { LPITEMIDLIST pidl; LPMALLOC pShellMalloc; char szDir[MAX_PATH];

if(SUCCEEDED(SHGetMalloc(&pShellMalloc))) { if(SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &pidl))) { // 如果成功返回true if(SHGetPathFromIDList(pidl, szDir)) { Label1->Caption = szDir; }

pShellMalloc->Free(pidl); }

pShellMalloc->Release(); } } //---------------------------------------------------------------------- 注意: 有些目录是空的。有些特定的目录在这个文件系统上并没有一个相应的目录。

取得本地internet机器的名字及IP地址

一、下面的例子使用 Winsock API 取得本地主机的名字及地址 void __fastcall TForm1::Button1Click(TObject *Sender) { hostent *p; char s[128]; char *p2;

//Get the computer name gethostname(s, 128); p = gethostbyname(s); Memo1->Lines->Add(p->h_name);

//Get the IpAddress p2 = inet_ntoa(*((in_addr *)p->h_addr)); Memo1->Lines->Add(p2); }

void __fastcall TForm1::FormCreate(TObject *Sender) { WORD wVersionRequested; WSADATA wsaData;

//Start up WinSock wVersionRequested = MAKEWORD(1, 1); WSAStartup(wVersionRequested, &wsaData); }

void __fastcall TForm1::FormDestroy(TObject *Sender) { WSACleanup(); }

搜索更多相关主题的帖子: Builder 技巧 
2004-04-27 11:21
ww110
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2004-10-12
收藏
得分:0 
大侠,我是一学C++的新手,能不能帮我编一用于人事管理的类,只需体现一些简单的属性就行.
2004-10-12 17:31
快速回复:C++Builder使用技巧集再续
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014678 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved