English 中文(简体)
通过温斯克提供关键缓冲板
原标题:Sending a keyboard buffer via Winsock
  • 时间:2011-04-02 07:23:16
  •  标签:
  • c++
  • winsock

现在,WINSOCKs是新鲜的,而不是C++的超量,我也这样说。 我撰写了一个网络Server和网络校友班,主要来自MSDN辅导。 客户将分送服务器256个大小的果园,包括每个标准键盘的状态(0意味着钥匙没有受到压力,1个意味着正在受到压力)。

在操作守则时,我首先开始服务器,然后开始客户。 他们相互交错。 然后,要求客户发出关键板缓冲。 缓冲器被送去,但服务器在以下几处hang:

receiveResult = recv(theClient, buffer, sizeof(buffer), 0);

每一类别中的“钥匙”变量是每个关键国家的char钥匙[256]。

下面是网络Server一旦启动就会出现的 lo:

char buffer[256];
int receiveResult, sendResult;

// Receive from the client
do
{
    receiveResult = recv(theClient, buffer, sizeof(buffer), 0);
    if (receiveResult > 0 )
    {
        sendResult = send(theClient, buffer, receiveResult, 0);
        if (sendResult == SOCKET_ERROR)
        {
            sendResult = WSAGetLastError();
            JBS::reportSocketError(nret, "server send()");
            closesocket(theClient);
            WSACleanup();
            return;
        }
        else
        {
            memcpy(keys, buffer, sizeof(keys));
        }
    }

    else if (receiveResult == 0)
        cout << "Server closing." << endl;
    else
    {
        receiveResult = WSAGetLastError();
        JBS::reportSocketError(nret, "server receive()");
        closesocket(theClient);
        WSACleanup();
        return;
    }
} while (receiveResult > 0);

这里是网络发送方法:

char buffer[256];
memcpy(buffer, keys, sizeof(buffer));

nret = send(theSocket, buffer, sizeof(buffer),0);
if (nret == SOCKET_ERROR)
{
    nret = WSAGetLastError();
    JBS::reportSocketError(nret, "client send()");
    closesocket(theSocket);
    WSACleanup();
} 
do
{   
    char buff[256];
    nret = recv(theSocket, buff, sizeof(buff), 0);
    if (nret > 0)
    {
        memcpy(keys, buff, sizeof(keys));
    }
    else if (nret == 0)
        cout << "Server connection closed" << endl;
    else
    {
        nret = WSAGetLastError();
        JBS::reportSocketError(nret, "client receive()");
        closesocket(theSocket);
        WSACleanup();
    }

} while (nret > 0);

正如我所说的那样,在客户和服务器之间建立了联系,但接收部分的流程似乎没有发挥作用。 希望得到任何帮助。

网络启动方法:

sockVersion = MAKEWORD(1, 1);

// Initialize Winsock as before
WSAStartup(sockVersion, &wsaData);

// Store information about the server
LPHOSTENT hostEntry;

hostEntry = gethostbyname(serverAddress);     // Specifying the server by its name;

if (!hostEntry) {
    nret = WSAGetLastError();
    JBS::reportSocketError(nret, "client gethostbyname()");         // Report the error as before
    closesocket(theSocket);
    WSACleanup();
}

// Create the socket
theSocket = socket(AF_INET,                      // Go over TCP/IP
    SOCK_STREAM,                  // This is a stream-oriented socket
    IPPROTO_TCP);                 // Use TCP rather than UDP

if (theSocket == INVALID_SOCKET) {
    nret = WSAGetLastError();
    JBS::reportSocketError(nret, "client socket()");
    closesocket(theSocket);
    WSACleanup();
}

// Fill a SOCKADDR_IN struct with address information
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port = htons(PORT);              // Change to network-byte order and
                                                // insert into port field

// Connect to the server
nret = connect(theSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

if (nret == SOCKET_ERROR) 
{
    nret = WSAGetLastError();
    JBS::reportSocketError(nret, "client connect()");
    closesocket(theSocket);
    WSACleanup();
}
// Successfully connected!
started = true;
最佳回答

Problem ended up being how I was assigning the values in the keyBuffer. I was doing

void key(unsigned char key, int x, int y)
{
    player.keyDown[key] = 1;
}

void key(unsigned char key, int x, int y)
{
    player.keyDown[key] =  1 ;
}
问题回答

在客户法典中,你写道:

char buff[256];
nret = recv(theSocket, buff, (int)strlen(buff), 0);

这意味着,你希望将数据输入一个长度为strlen(buff)的缓冲地带。 遗憾的是,strlen(>>将string内<>>的长度,即缓冲区内任何UNL特性之前的数据的长度。 您的汇编者很聪明才可以开始使用<条码>buff,其特性为strlen(buf)回报0,这意味着你希望收到0份数据。 因此,<代码>recv()不接受任何内容。

您指的是:

nret = recv(theSocket, buff, sizeof(buff), 0);

(if you tried compiling your program using the Release build, it would have crashed happily, because buff would then not be initialized, and strlen() would have returned a pretty random result which would have caused the program to access an invalid memory address...)

i should add that the way you declare your buffer is unfortunate: you have an array of booleans (value 1 or 0 depending of the state of keys). a boolean is not a char. a strict declaration should be bool buff[256]...





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?