我要自己发送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