TCP server Socket编程 VC++6.0

来源:互联网 发布:大数据交易市场现状 编辑:程序博客网 时间:2024/05/29 03:57

研二  wifi嗅探项目  第一阶段 数据提取与分析

#include <stdio.h>  
#include <winsock2.h>  
  
#pragma comment(lib,"ws2_32.lib")  
  
int main(int argc, char* argv[])  
{  
    //一、WSAStartup函数初始化Winsock 
    WORD sockVersion = MAKEWORD(2,2);  
    WSADATA wsaData;  
    if(WSAStartup(sockVersion, &wsaData)!=0)  //使用Winsocket函数之前,必须首先调用WSAStartup初始化ws2_32.dll
    {  
        return 0;  
    }  
  
    //二、socket函数创建套接字  
    SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  //AF_INET指定协议族为Internet协议;SOCK_STREAM称为流套接口,对应于TCP协议;IPPROTO_TCP指定所用的协议为TCP协议

    if(slisten == INVALID_SOCKET)  //函数socket有错误返回INVALID_SOCKET
    {  
        printf("socket error !");  
        return 0;  
    }  
  
    //三、结构体内绑定IP、端口;bind函数绑定套接口  
    sockaddr_in sin;              //INET协议族地址结构
    sin.sin_family = AF_INET;     //地址族
    sin.sin_port = htons(8080);   //16位的IP端口  自己的应用程序的端口号需设置为5001-65535之间 
    sin.sin_addr.s_addr = INADDR_ANY;   

//32位的iPv4地址  INADDR_ANY表示本地的任意以太网接口地址


    if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)  //bind绑定套接口 slisten为socket函数已创建的套接口描述字  (LPSOCKADDR)&sin为仅供套接口使用的本地地址的通用地址指针  最后一个参数为sin指针长度  bind函数有错返回SOCKET_ERROR

    {  
        printf("bind error !");  
    }  
  
    //四、listen函数开始监听  
    if(listen(slisten, SOMAXCONN) == SOCKET_ERROR)  //listen函数用于服务器端,connect函数用于客户端。listen函数负责通知进程接收连接请求,同时指定排队等待的最大连接数,一般为5,设置为SOMAXCONN则默认环境中可得的最大值。slisten为经socket函数创建,bind函数绑定但未连接的套接口描述字

    {  
        printf("listen error !");  
        return 0;  
    }  
  
    //循环接收数据  
    SOCKET sClient;  
    sockaddr_in remoteAddr;  
    int nAddrlen = sizeof(remoteAddr);  
#define hsize 2550      //缓冲区大小设置


char revData[hsize]; 
unsigned char revData1[hsize];        
    unsigned char lengh[2]={0};
int datalengh=0;        //数据长度
int j=0;                //作为帧首标志序号 作为数组序号的基准 
int flag=0;             //用于判断是否是第一个FE,避免将数据包中的FE判断为帧头


    while (true)  
    {  
        printf("等待连接...\n");  
        sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);  //accept函数等待接受连接请求 slisten为处于监听状态的套接口描述字 remoteAddr为用来接收外来连接的地址信息 nAddrlen为由remoteAddr所指的INET地址结构的长度
        if (sClient == INVALID_SOCKET)  //accept函数错误返回INVALID_SOCKET
        {  
            printf("accept error !");  
            continue;  
        }  
        printf("接收到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));  //打印收到的连接信息


        //recv函数从套接口接收数据   
        ZeroMemory(revData,hsize);  //清除数据接收缓冲区
        int ret = recv(sClient, revData, hsize, 0);  //sClient为套接口描述字 revData为用于接收数据的缓冲区指针 hsize为应用程序提供的缓冲区大小 0为标志值    
        if(ret>0)                                    //没有错误发生则返回接收的字节数,否则返回SOCKET_ERROR,返回0时,如果是UDP套接口,那么说明读到了一个没有应用数据的纯UDP头报文;如果是TCP连接,意味着对方已经关闭了连接
        {  
for (int i=0;i<ret;i++)
{
                revData1[i]=(unsigned char)(revData[i]);
printf("%02X ",(unsigned char)(revData[i]));
                if (flag==0)
{
if (revData1[i]==0xFE)
{
   j=i;      
flag=1;
}
}
}
flag=0;


//解析数据报长度 2 Byte  
            lengh[0]=revData1[j+1];
lengh[1]=revData1[j+2];
   datalengh=(int)lengh[1]<<8|(int)lengh[0];
            printf("\n数据长度为:%d  ",datalengh);     //数据长度包含第一个状态位 因此一定是9的倍数加一
//帧类型  1 Byte
            printf("  %02X上行数据包",revData1[j+3]); 
//设备ID  4 Byte
            printf("  设备ID:%02X.%02X.%02X.%02X\n",revData1[j+4],revData1[j+5],revData1[j+6],revData1[j+7]);  


//数据体
            printf("数据体:   设备状态%02X\n",revData1[j+8]); 
int q=9;             //数组序号
int timepc=0;        //时间偏差
int k=1;             //循环次数 也是设备个数
while (q < (datalengh+8) )
{   
   printf("WIFI设备%03d:MAC地址:%02X.%02X.%02X.%02X.%02X.%02X   RSSI:%d dbm   ",k,revData1[q],revData1[q+1],revData1[q+2],revData1[q+3],revData1[q+4],revData1[q+5],(char) revData1[q+6]); 
timepc=(int)revData1[q+8]<<8|(int)revData1[q+7];  //小端模式 所以后面是高位
                printf("时间偏差:%ds\n",timepc); 
k=k+1;
q=j+9*k;
}
            //校验值
            printf("校验值%02X\n",revData1[j+8+datalengh]); 
        }  
        closesocket(sClient);  
    }  
      
    closesocket(slisten);    //closesocket关闭一个存在的套接口
    WSACleanup();            //应用结束后必须调用WSACleanup函数终止ws2_32.dll的使用
    return 0;  


参考书籍:

TCP/IP协议及网络编程技术

Windows+Sockets网络开发:基于Visual+C++实现

WinSock网络编程经络

0 0
原创粉丝点击