Witam, piszę prosty program, który wysyła plik tekstowy przez sieć do już gotowego serwera. Używam asynchronicznych socketów opartych na komunikatach. Na msdn przeczytałem, że w przypadku braku miejsca w buforze po stronie serwera funkcja send zwraca kod błędu WSAEWOULDBLOCK, a dalsze wysyłanie będzie możliwe po wystąpieniu FD_WRITE. Początkowo wysyłałem małe pliki i wszystko było ok. Dane były całkowicie wysłane jednym send. Napisałem obsługę FD_WRITE i zacząłem wysyłać większe pliki . Zauważyłem, że FD_WRITE nie występuje. Wszystko wysyła się w jednym send, a aplikacja zdaje się blokować (problemy z przesuwaniem okna podczas wysyłania). FD_WRITE nie występuje nawet kiedy wysyłam plik 45MB a send nie zwraca WSAEWOULDBLOCK. Co robię źle? Zamieszczam kod:

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <fstream>
#include <string>

using namespace std;

#pragma comment(lib, "ws2_32.lib")

#define SOCKET_EVENT                WM_USER + 1
#define OK_BUTTON                        201

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

SOCKET hSocket;
char *buff = NULL;
unsigned bytes_sent = 0;
unsigned buff_size = 0;

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
        WNDCLASSEX wndclassex;
        HWND hMainWindow;
        MSG messages;

        wndclassex.hInstance = hThisInstance;
        wndclassex.cbSize = sizeof(WNDCLASSEX);
        wndclassex.cbWndExtra = 0;
        wndclassex.cbClsExtra = 0;
        wndclassex.lpfnWndProc = WndProc;
        wndclassex.lpszMenuName = 0;
        wndclassex.lpszClassName = "MainWindow";
        wndclassex.style = 0;
        wndclassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
        wndclassex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
        wndclassex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclassex.hbrBackground = (HBRUSH)COLOR_WINDOW;

        if(!RegisterClassEx(&wndclassex)) return -1;
        hMainWindow = CreateWindowEx(0, "MainWindow", "Klient", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, HWND_DESKTOP, 0, hThisInstance, 0);
        if(hMainWindow == NULL) return -1;

        ShowWindow(hMainWindow, nShowCmd);
        UpdateWindow(hMainWindow);

        while(true) {
                if(PeekMessage(&messages, 0, 0, 0, PM_REMOVE)) {
                        if(messages.message == WM_QUIT) break;
                        TranslateMessage(&messages);
                        DispatchMessage(&messages);
                }
                else WaitMessage();
        }

        return messages.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
        switch(uMsg) {
                case WM_CREATE: {
                        WSADATA wsadata;
                        
                        if(WSAStartup(MAKEWORD(2, 2), &wsadata) != 0) break;
                        hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                        if(hSocket == INVALID_SOCKET) {
                                WSACleanup();
                                break;
                        }

                        WSAAsyncSelect(hSocket, hWnd, SOCKET_EVENT, FD_WRITE | FD_READ | FD_CONNECT | FD_CLOSE);
                        sockaddr_in sockAddr;
                        sockAddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.14");
                        sockAddr.sin_port = htons(1234);
                        sockAddr.sin_family = AF_INET;

                        connect(hSocket, (sockaddr*)&sockAddr, sizeof(sockAddr));

                        HWND hOkButton = CreateWindowEx(0, "BUTTON", "OK", WS_CHILD | WS_VISIBLE, 5, 5, 60, 23, hWnd, (HMENU)OK_BUTTON, GetModuleHandle(0), 0);
                        HFONT hDefaultFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
                        SendMessage(hOkButton, WM_SETFONT, (WPARAM)hDefaultFont, 0);
                } break;
                case SOCKET_EVENT: {
                        if(WSAGETSELECTERROR(lParam)) break;
                        switch(WSAGETSELECTEVENT(lParam)) {
                                case FD_CONNECT:
                                        MessageBox(hWnd, "Connected to the server.", "info", 0);
                                break;
                                case FD_READ:
                                        MessageBox(hWnd, "FD_READ", "info", 0);
                                break;
                                case FD_WRITE:
                                        ofstream trace_file("trace.txt", ios::app);
                                        static int counter = 0;
                                        trace_file << "fd_write: " << ++counter << endl;
                                        if(buff == NULL) break;
                                        if(buff_size == bytes_sent) {
                                                delete []buff;
                                                buff = NULL;
                                                buff_size = 0;
                                                bytes_sent = 0;
                                                break;
                                        }
                                        char *temp_buff = new char[sizeof(buff) - bytes_sent];
                                        strcpy_s(temp_buff, sizeof(buff) - bytes_sent, buff);
                                        bytes_sent += send(hSocket, temp_buff, sizeof(temp_buff), 0);
                                break;
                        }
                } break;
                case WM_COMMAND: {
                        switch(LOWORD(wParam)) {
                                case OK_BUTTON: {
                                        ifstream file("plik.txt");
                                        string line;
                                        string strFile;

                                        while(getline(file, line)) {
                                                strFile += line + '\n';
                                        }

                                        buff = new char[strFile.length()];
                                        buff_size = strFile.length();
                                        strcpy(buff, strFile.c_str());

                                        bytes_sent = send(hSocket, buff, strlen(buff), 0);

                                        if(bytes_sent == SOCKET_ERROR) {
                                                if(WSAGetLastError() == WSAEWOULDBLOCK) {
                                                        MessageBox(hWnd, "WSAEWOULDBLOCK", "info", MB_ICONINFORMATION);
                                                }
                                        }
                                } break;
                        }
                } break;
                case WM_DESTROY:
                        closesocket(hSocket);
                        PostQuitMessage(0);
                break;
                default: return DefWindowProc(hWnd, uMsg, wParam, lParam);
        }

        return 0;
}