当前位置:编程学习 > C#/ASP.NET >>

我要自己发送IP+TCP+HTTP,请问哪里错了

Server.exe:接受发送的数据
#include "stdafx.h"
//#include   <ws2tcpip.h>  
//#include   <ws2tcpip.h>  

#include  <winsock2.h>
#include   <ws2tcpip.h>  

#include  <stdio.h>
typedef   struct   ip_hdr   //定义IP首部   
{   
BYTE   ver:4; //4位首部长度,4位IP版本号
BYTE   head_len:4;
BYTE   tos;   //8位服务类型TOS   
WORD  total_len;   //16位总长度(字节)   
WORD   ident;   //16位标识   
WORD   not_use:1;   //3位标志位  
WORD   DF:1;
WORD   MF:1;
WORD   off:13; 
BYTE   ttl;   //8位生存时间   TTL   
BYTE   iProtocol;   //8位协议   (TCP,   UDP   或其他)   
WORD   checksum;   //16位IP首部校验和   
DWORD   sourceIP;   //32位源IP地址   
DWORD   destIP;   //32位目的IP地址 
//Ip_Options Options;
 
}IP_HEADER;   
typedef IP_HEADER *LPIP;


typedef struct _TCP 

WORD SrcPort; 
WORD DstPort; 
DWORD SeqNum; 
DWORD AckNum; 
WORD head_len:4;
WORD protect:6;
WORD URG:1;
WORD ACK:1;
WORD PSH:1;
WORD RST:1;
WORD SYN:1;
WORD FIN:1;
WORD Window; 
WORD Chksum; 
WORD UrgPtr; 
} TCP; 

typedef TCP *LPTCP;
#define   SIO_RCVALL                         _WSAIOW(IOC_VENDOR,1) 
/* 这个程序建立一个套接字,然后开始无限循环;每当它通过循环接收到一个连接,则打印出一个信息。当连接断开,或接收到终止信息,则此连接结束,程序再接收一个新的连接。命令行的格式是:streams */
int main( )
{
WSADATA wsaData;
int sock, length;
struct sockaddr_in server;
struct sockaddr tcpaddr;
int msgsock;
char buf[10000];
int rval, len;
int flag=0;
/* 建立套接字 */
WSAStartup(MAKEWORD(2,2),&wsaData);
sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (sock==INVALID_SOCKET) {
printf("opening stream socket\n");
return 0;
}
if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(const char*)&flag,sizeof(flag))==SOCKET_ERROR){
   printf("setsockopt error\n");
   return 0;
}
/* 使用任意端口命名套接字 */ 
server.sin_family = AF_INET;
server.sin_port = htons(7000);
server.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) ==SOCKET_ERROR) {
printf("binding stream socket\n");
return 0;
}
/* 找出指定的端口号并打印出来 */
length = sizeof(server);
/*if (getsockname(sock, (struct sockaddr *)&server, &length) ==SOCKET_ERROR) {
printf("getting socket name\n");
return 0;
}*/
printf("socket port #%d\n", ntohs(server.sin_port));
/* 开始接收连接 */
listen(sock, 5);
len = sizeof(struct sockaddr);
do {
msgsock = accept(sock, (struct sockaddr *)&tcpaddr, (int *)&len);
if (msgsock ==INVALID_SOCKET)
{
printf("accept error\n");
printf("%d\n",WSAGetLastError());
return 0;
}
else do{
memset(buf, 0, sizeof(buf));
if ((rval = recv(msgsock, buf, 10000,0)) < 0)
printf("reading stream message\n");
if (rval == 0)
printf("ending connection \n");
else
printf("-->%s\n", buf);
}while (rval != 0);
closesocket(msgsock);
} while (1);
/* 因为这个程序已经有了一个无限循环,所以套接字"sock"从来不显式关闭。然而,当进程被杀死或正常终止时,所有套接字都将自动地被关闭。*/
return 0;
}


Client.exe:封装数据包发送:
#include "stdafx.h"
#include <winsock2.h>
#include   <ws2tcpip.h>  

#define DATA "half a league, half a league ..."
typedef   struct   ip_hdr   //定义IP首部   
{   
BYTE   ver:4; //4位首部长度,4位IP版本号
BYTE   head_len:4;
BYTE   tos;   //8位服务类型TOS   
WORD  total_len;   //16位总长度(字节)   
WORD   ident;   //16位标识   
WORD   not_use:1;   //3位标志位  
WORD   DF:1;
WORD   MF:1;
WORD   off:13; 
BYTE   ttl;   //8位生存时间   TTL   
BYTE   iProtocol;   //8位协议   (TCP,   UDP   或其他)   
WORD   checksum;   //16位IP首部校验和   
DWORD   sourceIP;   //32位源IP地址   
DWORD   destIP;   //32位目的IP地址 
//Ip_Options Options;
 
}IP_HEADER;   
typedef IP_HEADER *LPIP;


typedef struct _TCP 

WORD SrcPort; 
WORD DstPort; 
DWORD SeqNum; 
DWORD AckNum; 
WORD head_len:4;
WORD protect:6;
WORD URG:1;
WORD ACK:1;
WORD PSH:1;
WORD RST:1;
WORD SYN:1;
WORD FIN:1;
WORD Window; 
WORD Chksum; 
WORD UrgPtr; 
} TCP; 

typedef TCP *LPTCP;

u_short in_cksum(u_short* addr,int len){
  register int nleft=len;
  register u_short *w=addr;
  register u_short answer;
  register int sum=0;
  while(nleft>1){
    sum+=*w++;
nleft-=2;
  }
  if(nleft==1){
    u_short u=0;
*(u_char*)(&u)=*(u_char*)w;
sum+=u;
  }
  sum=(sum>>16)+(sum&0xffff);
  sum+=(sum>>16);
  answer=~sum;
  return (answer);
}
void fillTCP(LPTCP tcphdr){

static nSeq=1;
    tcphdr->ACK=0;
tcphdr->AckNum=0;
tcphdr->Chksum=0;
tcphdr->PSH=0;
tcphdr->RST=0;
tcphdr->SYN=0;
tcphdr->URG=0;
tcphdr->UrgPtr=0;
    tcphdr->Window=0;
tcphdr->SrcPort=htons(5000);
tcphdr->DstPort=htons(6000);
    tcphdr->head_len=5;
    tcphdr->protect=0;
tcphdr->SeqNum=nSeq++;
tcphdr->Chksum=in_cksum((u_short*)tcphdr,sizeof(TCP));
}

char* fillIP(LPIP iphdr,LPTCP tcphdr){
char* buf;
static nId=1;
 char* httpHdr="HTTP/1.1 200 OK\r\nServer:BigFox Server1.0\r\n\r\n";
fillTCP(tcphdr);
 iphdr->checksum=0;
 iphdr->MF=0;
 iphdr->not_use=0;
 iphdr->off=0;
 iphdr->tos=0;
 iphdr->ttl=128;
 
 iphdr->ver=4;
 iphdr->head_len=5;
 iphdr->ident=nId++;
 iphdr->iProtocol=6;
 iphdr->DF=1;
 iphdr->sourceIP=htonl(INADDR_ANY);
 iphdr->destIP=htonl(INADDR_ANY);
 strcpy(buf,(char*)iphdr);
 strcat(buf,(char*)tcphdr);
 strcat(buf,httpHdr);
 int buf_size=strlen(buf);
 int http_len=strlen(httpHdr);
 iphdr->total_len=iphdr->head_len+tcphdr->head_len+(WORD)http_len;
 iphdr->checksum=in_cksum((u_short*)buf,buf_size);
 strcpy(buf,(char*)iphdr);
 strcat(buf,(char*)tcphdr);
 strcat(buf,httpHdr);
 
return buf;
}


void fillHTTP(char* httpHdr){
   httpHdr="HTTP/1.1 200 OK\r\nServer:BigFox Server1.0\r\n\r\n";
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
int flag=1;
int sock;
struct sockaddr_in server;
char buf[1024];
/* 建立套接字 */
WSAStartup(MAKEWORD(2,2),&wsaData);

sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock ==INVALID_SOCKET) {
printf("opening stream socket\n");
return 0;
}

setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(const char*)&flag,sizeof(flag));
LPIP iphdr;
LPTCP tcphdr;
char* bufs;
iphdr->destIP=inet_addr("127.0.0.1");
iphdr->sourceIP=inet_addr("127.0.0.1");

/* 使用命令行中指定的名字连接套接字 */
server.sin_family = AF_INET;
server.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");


server.sin_port = htons(7000);
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) ==SOCKET_ERROR) {
printf("connecting stream socket\n");
return 0;
}
fillIP(iphdr,tcphdr);
if (send(sock,bufs,sizeof(buf),0) < 0)
printf("sending on stream socket");
closesocket(sock);


return 0;
}
--------------------编程问答-------------------- 你没发现你这个程序一运行到了do{}while循环就无法出来吗?你可以调试跟踪下试下

这样的话,主线程卡在循环里面出不来,后面的代码无法执行,程序可以正常运行么?

一般这种程序都是采用另外开线程来做的,把你的循环放在线程函数里面做的。。。
补充:.NET技术 ,  VC.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,