5

为什么这个程序不能连接到套接字?

我知道这会WSAStartup失败,但我不知道如何使用它。

#include "StdAfx.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <string.h>
#include <errno.h>

#pragma comment(lib, "ws2_32.lib")
int sockd;

#define SocketErrno (WSAGetLastError())
#define bcopy(src,dest,len) memmove(dest,src,len)

typedef signed char int8;
typedef signed long int32;

inline int WriteInt8(char *buf, int pos, int8 value) { buf[pos] = (int8)(value); return 1; }
inline int WriteInt32(char *buf, int pos, int32 value) { buf[pos] = (int8)(value >> 24); buf[pos+1] = (int8)(value >> 16); buf[pos+2] = (int8)(value >> 8); buf[pos+3] = (int8)(value); return 4; }
inline int WriteASCII(char *start_buf, int pos, const char *start, int length) { int startPos = 0; char *buf = &start_buf[pos]; for (int i = 0; i < length; ++i) { buf[i] = start[startPos]; if (start[startPos]) ++startPos; } return length; }

size_t writen(int fd, const char *vptr, size_t n)
{
    size_t nleft;
    size_t nwritten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) 
    {
        if ( (nwritten = writen(fd, ptr, nleft)) <= 0)
        {
            if (errno == EINTR)
                nwritten = 0;
            else
                return(-1);
        }

        nleft -= nwritten;
        ptr += nwritten;
    }
    return(n);
}

bool login(char *Username, char *Password, int characterID)
{
    char buffer[8192];
    int pos = 0;
    pos += WriteInt8(buffer, pos, 0x91u);
    pos += WriteInt8(buffer, pos, 58);
    pos += WriteInt8(buffer, pos, 0xFFu);
    pos += WriteInt8(buffer, pos, 55);
    pos += WriteInt8(buffer, pos, 40);
    pos += WriteASCII(buffer, pos, Username, 30);
    pos += WriteASCII(buffer, pos, Password, 30);

    if( writen(sockd, buffer, 65) < 65)
        return false;
    WriteInt8(buffer, 0, 0x5D);
    WriteInt32(buffer, 65, characterID);

    if( writen(sockd, buffer, 73) < 73)
        return false;

    return true;
}

bool connect(char *ServerAddress, int ServerPort)
{

    struct sockaddr_in servaddr;

    if ( (sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
        return false;

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(ServerPort);

    if ( inet_pton(AF_INET, ServerAddress, &servaddr.sin_addr) <= 0 )
        return false;

    if ( connect(sockd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 )
        return false;

    char seed[4] = { 0x3au, 0xFFu, 55, 40 };

    if( writen(sockd, seed, 4) < 0)
        return false;

    return true;
}

int main(int argc, char * argv[])
{


    bool wArgs = true;

    if (argc == 1)
    {
        wArgs = false;
    }
    else if (argc != 4)
    {
        printf("USAGE: %s User Password CharacterNumber\n", argv[0]); 
        return 51;
    }

    printf("stuff");

    char *user = new char[20];
    char *pass = new char[20];
    int pg;

    if (wArgs)
    {
        user = argv[1];
        pass = argv[2];
        pg = atoi(argv[3]);
    }
    else
    {
        printf("*****************************************\n\nUser: ");
        scanf("%s", user);
        printf("Pass: ");
        scanf("%s", pass);
        printf("Character Number: ");
        scanf("%d", &pg);
        printf("\n*****************************************\n");
    }

    if (!connect("ip hidden,port hidden))
        {
    printf("Error at socket(): %ld\n", WSAGetLastError());

    return 1;
}


    if (!login(user, pass, pg))
        return 103;

    char version[12] = { 0xBDu, 0x00u, 0x0Cu, 0x36u, 0x2Eu, 0x30u, 0x2Eu, 0x31u, 0x2Eu, 0x31u, 0x30u, 0x00 };

    if ( writen(sockd, version, 12) < 0 )
        return 105;

    for(;;)
    {
        //12 00 09 24 32 31 20 30 00     ...l.....$21 0.

        char refresh[9] = { 0x12, 0x00, 0x09, 0x24, 0x32, 0x31, 0x20, 0x30, 0x00 };
        if( writen(sockd, refresh, 9) < 0)
            return 104;
        Sleep(40);
    }
    return 1;
}
4

1 回答 1

12

10093 是WSANOTINITIALISED,表示WSAStartup()尚未调用。的文档非常清楚,WSAStartup如果有点冗长,甚至包括一个相当完整的示例。

必须WSAStartup在使用任何其他 Winsock 函数之前调用:

wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsaData);

在学习进行 WinSock 编程时,您可能还想查看WinSock 常见问题解答。

于 2013-06-12T16:34:48.423 回答