windows socket 通信问题

今天看了《C++ 揭秘与防范黑客编程》(作者: 翼云),看了2.4节的程序后,自己写了一下。

客户端:

main.cpp
  1 //file name: main.cpp
  2 
  3 #include <WinSock2.h>
  4 #include <iostream>
  5 #include <assert.h>
  6 
  7 #pragma comment(lib, "ws2_32")
  8 
  9 using namespace std;
 10 
 11 //存储系统信息的结构体
 12 typedef struct _SYS_INFO
 13 {
 14     char m_szComputerName[MAXBYTE];
 15     char m_szUserName[MAXBYTE];
 16     OSVERSIONINFO m_sVer;
 17 }SYS_INFO, *PSYS_INFO;
 18 
 19 void ShowSysInfo( PSYS_INFO pInfo ) 
 20 {
 21     assert(NULL != pInfo);
 22 
 23     if (VER_PLATFORM_WIN32_NT == pInfo->m_sVer.dwPlatformId)
 24     {
 25         if (5==pInfo->m_sVer.dwMajorVersion)
 26         {
 27             switch (pInfo->m_sVer.dwMinorVersion)
 28             {
 29             case 1:
 30                 cout<<"Windows XP";
 31                 break;
 32             case 0:
 33                 cout<<"Windows 2000";
 34                 break;
 35             case 2:
 36                 cout<<"Windows Server 2003";
 37                 break;
 38             }
 39         }
 40         if (6==pInfo->m_sVer.dwMajorVersion)
 41         {
 42             switch (pInfo->m_sVer.dwMinorVersion)
 43             {
 44             case 1:
 45                 cout<<"Windows 7";
 46                 break;
 47             case 0:
 48                 cout<<"Windows Server 2008 or Windows Vista";
 49                 break;
 50             }
 51         }
 52         cout<<" "<<pInfo->m_sVer.szCSDVersion<<endl;
 53     }
 54     else
 55     {
 56         cout<<"Other System"<<endl;
 57     }
 58     cout<<"Computer Name: "<<pInfo->m_szComputerName<<endl;
 59     cout<<"User Name: "<<pInfo->m_szUserName<<endl;
 60 }
 61 
 62 int main(int argc, char *argv)
 63 {
 64     //初始化ws2_32.dll
 65     WSADATA wsaData;
 66     if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
 67     {
 68         cout<<"初始化ws2_32.dll时出错,错误号为: "<<WSAGetLastError()<<endl;
 69         return -1;
 70     }
 71 
 72     //创建套接字
 73     SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 74     if (INVALID_SOCKET == s)
 75     {
 76         cout<<"创建套接字时出错,错误号为: "<<WSAGetLastError()<<endl;
 77         goto ERR0;
 78     }
 79     sockaddr_in sockAddr;
 80     sockAddr.sin_family = PF_INET;
 81     sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
 82     sockAddr.sin_port = htons(827);
 83 
 84     //建立连接
 85     if (SOCKET_ERROR == connect(s, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)))
 86     {
 87         cout<<"建立连接时出错,错误号为: "<<WSAGetLastError()<<endl;
 88         goto ERR;
 89     }
 90 
 91     //接收和发送数据
 92     char szBuffer[1024] = {0};
 93     char szCmd[MAXBYTE] = {0};
 94     while (true)
 95     {
 96         memset(szBuffer, 0, 1024);
 97         memset(szCmd, 0, MAXBYTE);
 98 
 99         int nRecv = recv(s, szBuffer, 1024, NULL);
100         if (0 == nRecv)
101         {
102             cout<<"连接已经被关闭"<<endl;
103             goto ERR;
104         }
105         if (SOCKET_ERROR == nRecv)
106         {
107             cout<<"接收数据时出错,错误号为: "<<WSAGetLastError()<<endl;
108             goto ERR;
109         }
110         cout<<szBuffer;
111 
112         cin>>szCmd;
113         int nSend = send(s, szCmd, MAXBYTE, NULL);
114         if (SOCKET_ERROR == nSend)
115         {
116             cout<<"发送数据时出错,错误号为: "<<WSAGetLastError()<<endl;
117             goto ERR;
118         }
119         
120         memset(szBuffer, 0, 1024);
121         nRecv = recv(s, szBuffer, 1024, NULL);
122         if (0 == nRecv)
123         {
124             cout<<"连接已经被关闭"<<endl;
125             goto ERR;
126         }
127         if (SOCKET_ERROR == nRecv)
128         {
129             cout<<"接收数据时出错,错误号为: "<<WSAGetLastError()<<endl;
130             goto ERR;
131         }
132 
133         if (0 == strcmp(szCmd, "getsysinfo"))
134         {
135             PSYS_INFO pInfo = (PSYS_INFO)szBuffer;
136             
137             ShowSysInfo(pInfo);
138         }
139         else
140         {
141             cout<<szBuffer<<endl;
142         }
143     }
144 
145 ERR:
146     closesocket(s);
147 ERR0:
148     WSACleanup();
149 
150     return 0;
151 }

服务器端:

control.h
//file name: control.h
#pragma once

#include <WinSock2.h>
#pragma comment(lib, "ws2_32")
#pragma comment(lib, "winmm.lib")

#define DISPATH_SUCCEED    (1)

#define    HELPMSG    "help - Show help menu \r\n"    \
                "getsysinfo - Get system information \r\n"    \
                "open - Open the CD-ROM \r\n"    \
                "close - Close the CD-ROM \r\n"    \
                "swap - Swap mouse button \r\n"    \
                "restore - Restore mouse button \r\n"    \
                "exit - Quit Shell"

//分发命令
LONG dispath(SOCKET sock, char *pCmd);

//存储系统信息的结构体
typedef struct _SYS_INFO
{
    char m_szComputerName[MAXBYTE];
    char m_szUserName[MAXBYTE];
    OSVERSIONINFO m_sVer;
}SYS_INFO, *PSYS_INFO;

//获取系统信息
LONG GetSysInfo(SYS_INFO &sysInfo);

//打开或关闭光驱
LONG SetCDAudio(bool bOpen);

//交换或还原鼠标左右键
void SetMouse(bool bSwap);
control.cpp
//file name: control.cpp

#include "control.h"
#include <assert.h>

LONG dispath( SOCKET sock, char *pCmd )
{
    LONG lRet = 0;
    
    if (NULL == pCmd)
    {
        return 0;
    }
    if (0 == strcmp(pCmd, "help"))
    {
        //发送帮助信息
        int nSend = send(sock, HELPMSG, strlen(HELPMSG)+sizeof(char), NULL);
        if (SOCKET_ERROR != nSend)
        {
            lRet = DISPATH_SUCCEED;
        }
    }
    else if (0 == strcmp(pCmd, "getsysinfo"))
    {
        //获取系统信息
        SYS_INFO sInfo = {0};
        sInfo.m_sVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        if (DISPATH_SUCCEED == GetSysInfo(sInfo))
        {
            int nSend = send(sock, (char*)&sInfo, sizeof(SYS_INFO), NULL);

            if (SOCKET_ERROR != lRet)
            {
                lRet = DISPATH_SUCCEED;
            }
        }
        else
        {
            int nSend = send(sock, "getsysinfo failed", strlen("open cdaudio door")+sizeof(char), NULL);
            if (SOCKET_ERROR != nSend)
            {
                lRet = DISPATH_SUCCEED;
            }
            else
            {
                lRet = WSAGetLastError();
            }
        }
    }
    else if (0 == strcmp(pCmd, "open"))
    {
        //打开光驱
        lRet = SetCDAudio(true);
        
        int nSend = send(sock, "open cdaudio door", strlen("open cdaudio door")+sizeof(char), NULL);
        if (SOCKET_ERROR != nSend)
        {
            lRet = DISPATH_SUCCEED;
        }
        else
        {
            lRet = WSAGetLastError();
        }
    }
    else if (0 == strcmp(pCmd, "close"))
    {
        //关闭光驱
        lRet = SetCDAudio(false);
        

        int nSend = send(sock, "close cdaudio door", strlen("open cdaudio door")+sizeof(char), NULL);
        if (SOCKET_ERROR != nSend)
        {
            lRet = DISPATH_SUCCEED;
        }
        else
        {
            lRet = WSAGetLastError();
        }
    }
    else if (0 == strcmp(pCmd, "swap"))
    {
        //交换鼠标左右键
        SetMouse(true);
        lRet = DISPATH_SUCCEED;

        int nSend = send(sock, "swap mouse buttons", strlen("open cdaudio door")+sizeof(char), NULL);
        if (SOCKET_ERROR != nSend)
        {
            lRet = DISPATH_SUCCEED;
        }
        else
        {
            lRet = WSAGetLastError();
        }
    }
    else if (0 == strcmp(pCmd, "restore"))
    {
        //恢复鼠标左右键
        SetMouse(false);
        lRet = DISPATH_SUCCEED;


        int nSend = send(sock, "restore mouse buttons", strlen("open cdaudio door")+sizeof(char), NULL);
        if (SOCKET_ERROR != nSend)
        {
            lRet = DISPATH_SUCCEED;
        }
        else
        {
            lRet = WSAGetLastError();
        }
    }
    else
    {
        //错误的命令
        int nSend = send(sock, "Error Commond line", sizeof(char)+strlen("Error Commond line"), NULL);
        if (SOCKET_ERROR != lRet)
        {
            lRet = DISPATH_SUCCEED;
        }
    }

    return lRet;
    
}

LONG GetSysInfo( SYS_INFO &sysInfo )
{
    LONG lRet = DISPATH_SUCCEED;
    
    lRet = GetVersionEx(&sysInfo.m_sVer);
    
    if (!lRet)
    {
        return GetLastError();
    }
    
    DWORD dwSize = MAXBYTE;
    lRet = GetComputerName(sysInfo.m_szComputerName, &dwSize);
    if (!lRet)
    {
        return GetLastError();
    }

    dwSize = MAXBYTE;
    lRet = GetUserName(sysInfo.m_szUserName, &dwSize);
    if (!lRet)
    {
        DWORD dwErr;
        dwErr = GetLastError();
        return dwErr;
        
    }

    return lRet;
}

LONG SetCDAudio( bool bOpen )
{
    LONG lRet = 0;
    if (bOpen)
    {
        lRet = mciSendString("set cdaudio door open", NULL, NULL, NULL);
    }
    else
    {
        lRet = mciSendString("set cdaudio door close", NULL, NULL, NULL);
    }
    
    if (0 != lRet)
    {
        return lRet;
    }
    
    return DISPATH_SUCCEED;
}

void SetMouse( bool bSwap )
{
    SwapMouseButton(bSwap);
}
main.cpp
//file name: main.cpp

#include <iostream>
#include <WinSock2.h>
#include "control.h"

#pragma comment(lib, "ws2_32")

using namespace std;

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET s;
    SOCKET clientSocket;

    if (0 != WSAStartup(MAKEWORD(2,2), &wsaData))
    {
        cout<<"初始化ws2_32.dll失败,错误号为: "<<WSAGetLastError()<<endl;
        return 0;
    }

    //创建套接字
    s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == s)
    {
        cout<<"创建套接字时发生错误,错误号为: "<<WSAGetLastError()<<endl;
        goto ERR0;
    }
    sockaddr_in sockAddr;
    sockAddr.sin_family = PF_INET;
    sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    sockAddr.sin_port = htons(827);

    //绑定套接字
    if(SOCKET_ERROR == bind(s, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)))
    {
        cout<<"绑定套接字时发生错误,错误号为: "<<WSAGetLastError()<<endl;
        goto ERR1;
    }

    //进行监听
    if (SOCKET_ERROR == listen(s, 1))
    {
        cout<<"创建监听时发生错误,错误号为: "<<WSAGetLastError()<<endl;
        goto ERR1;
    }

    //创建用来向客服端发送数据的套接字
    SOCKADDR ClientAddr;
    int nSize = sizeof(SOCKADDR);
    clientSocket = accept(s, (SOCKADDR*)&ClientAddr, &nSize);
    if (INVALID_SOCKET == clientSocket)
    {
        cout<<"创建套接字时发生错误,错误号为: "<<WSAGetLastError()<<endl;
        goto ERR1;
    }

    int nSend = 0;
    int nRecv = 0;
    //循环发送消息给客服端,并且对客服端发来的信息进行分发
    char szRecv[MAXBYTE] = {0};
    while (true)
    {
        //发送数据
        nSend = send(clientSocket, "Shell>> ", strlen("Shell>> ")+sizeof(char), NULL);
        if (SOCKET_ERROR == nSend)
        {
            cout<<"发送数据时发生错误,错误号为: "<<WSAGetLastError()<<endl;
            goto ERR;
        }

        //接收客服端数据
        memset(szRecv, 0, MAXBYTE);
        nRecv = recv(clientSocket, szRecv, MAXBYTE, NULL);
        if (0 == nRecv)
        {
            cout<<"连接已经被断开"<<endl;
            goto ERR;
        }
        if (SOCKET_ERROR == nRecv)
        {
            cout<<"接收数据时发生错误,错误号为: "<<WSAGetLastError()<<endl;
            goto ERR;
        }
    
        if (0 == strcmp(szRecv, "exit"))
        {
            break;
        }
        LONG lRet = dispath(clientSocket, szRecv);
        if (DISPATH_SUCCEED != lRet)
        {
            cout<<"分发的命令处理失败, 错误号为: "<<lRet<<endl;
            goto ERR;
        }
    }

ERR:
    closesocket(clientSocket);
ERR1:
    closesocket(s);
ERR0:
    WSACleanup();

    return 0;
}

不知道为什么接收到的结构体,会有乱码,懂不起鸟,只能慢慢Debug了。我是用的vs2005,在朋友vc6下面就没有乱码,不明白呀。

 

明白了,竟然是很2的编码问题,服务器端没有选择Unicode字符集,服务器端却选了,然后用了一个char数组去存收到的Unicode字符串。

posted @ 2013-03-15 15:30  Leige  阅读(308)  评论(0编辑  收藏  举报