搜索文章:

首页  |  Java技术  |  Asp.net  |  Asp编程  |  VC/C++  |  Delphi  |  VB编程

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();
 }

()

相关文章:
© 2006   www.java-asp.net