2012-09-25 27 views
0

我有一個問題,我一直在試圖解決它已經一個星期!但我沒有在互聯網上得到任何信息,這導致瞭解決方案。win32 winsocket

問題如下: 我嘗試爲WIndows Embedded編寫一個簡單的Win32-GUI-Application。我正在使用Visual Studio 2008 Professional。在應用程序開始時,應該建立到服務器的連接。這是我的代碼到目前爲止:

// Test.cpp : Definiert den Einstiegspunkt für die Anwendung. 
// 

#include "stdafx.h" 
#include "Test.h" 
#include <windows.h> 
#include <winsock2.h> 
#include <ws2tcpip.h> 
#include <stdlib.h> 
#include <stdio.h> 


// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib 
#pragma comment (lib, "Ws2_32.lib") 
#pragma comment (lib, "Mswsock.lib") 
#pragma comment (lib, "AdvApi32.lib") 


#define DEFAULT_BUFLEN 512 
#define DEFAULT_PORT "27015" 
#define MAX_LOADSTRING 100 

// Globale Variablen: 
HINSTANCE   g_hInst;   // Aktuelle Instanz 
HWND    g_hWndMenuBar;  // Menüleistenhandle 

// Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen: 
ATOM   MyRegisterClass(HINSTANCE, LPTSTR); 
BOOL   InitInstance(HINSTANCE, int); 
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 

int WINAPI WinMain(HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPTSTR lpCmdLine, 
        int  nCmdShow) 
{ 
    MSG msg; 

    WSADATA wsaData; 
    SOCKET ConnectSocket = INVALID_SOCKET; 
    struct addrinfo *result = NULL, 
        *ptr = NULL, 
        hints; 
    char *sendbuf = "this is a test"; 
    char recvbuf[DEFAULT_BUFLEN]; 
    int iResult; 
    int recvbuflen = DEFAULT_BUFLEN; 

    // Initialize Winsock 
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData); 
    if (iResult != 0) { 
     ; 
     return 1; 
    } 

    ZeroMemory(&hints, sizeof(hints)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_protocol = IPPROTO_TCP; 

    // Resolve the server address and port 
    iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result); 
    if (iResult != 0) { 
     ; 
     WSACleanup(); 
     return 1; 
    } 

    // Attempt to connect to an address until one succeeds 
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { 

     // Create a SOCKET for connecting to server 
     ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
      ptr->ai_protocol); 
     if (ConnectSocket == INVALID_SOCKET) { 
      ; 
      WSACleanup(); 
      return 1; 
     } 

     // Connect to server. 
     iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); 
     if (iResult == SOCKET_ERROR) { 
      closesocket(ConnectSocket); 
      ConnectSocket = INVALID_SOCKET; 
      continue; 
     } 
     break; 
    } 

    freeaddrinfo(result); 

    if (ConnectSocket == INVALID_SOCKET) { 
     ; 
     WSACleanup(); 
     return 1; 
    } 

    // Send an initial buffer 
    iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0); 
    if (iResult == SOCKET_ERROR) { 
     ; 
     closesocket(ConnectSocket); 
     WSACleanup(); 
     return 1; 
    } 


    // shutdown the connection since no more data will be sent 
    iResult = shutdown(ConnectSocket, SD_SEND); 
    if (iResult == SOCKET_ERROR) { 
     ; 
     closesocket(ConnectSocket); 
     WSACleanup(); 
     return 1; 
    } 

    // Receive until the peer closes the connection 
    do { 

     iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0); 
     if (iResult > 0) 
      ; 
     else if (iResult == 0) 
      ; 
     else 
      ; 

    } while(iResult > 0); 

    // cleanup 
    closesocket(ConnectSocket); 
    WSACleanup(); 

    // Anwendungsinitialisierung ausführen: 
    if (!InitInstance(hInstance, nCmdShow)) 
    { 
     return FALSE; 
    } 

    HACCEL hAccelTable; 
    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST)); 

    // Hauptmeldungsschleife: 
    while (GetMessage(&msg, NULL, 0, 0)) 
    { 
     if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 

    return (int) msg.wParam; 
} 

// 
// FUNKTION: MyRegisterClass() 
// 
// ZWECK: Registriert die Fensterklasse. 
// 
// KOMMENTARE: 
// 
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) 
{ 
    WNDCLASS wc; 

    wc.style   = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance  = hInstance; 
    wc.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST)); 
    wc.hCursor  = 0; 
    wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName = 0; 
    wc.lpszClassName = szWindowClass; 

    return RegisterClass(&wc); 
} 

// 
// FUNKTION: InitInstance(HINSTANCE, int) 
// 
// ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster. 
// 
// KOMMENTARE: 
// 
//  In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das 
//  Hauptprogrammfenster wird erstellt und angezeigt. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
    HWND hWnd; 
    TCHAR szTitle[MAX_LOADSTRING];  // Titelleistentext 
    TCHAR szWindowClass[MAX_LOADSTRING]; // Klassenname des Hauptfensters 

    g_hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern 

    // SHInitExtraControls sollte einmal während der Initialisierung der Anwendung aufgerufen werden, um alle 
    // gerätespezifischen Steuerelemente wie CAPEDIT und SIPPREF zu initialisieren. 
    SHInitExtraControls(); 

    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
    LoadString(hInstance, IDC_TEST, szWindowClass, MAX_LOADSTRING); 

    //Bei bereits gestarteter Ausführung Fokus auf das Fenster verschieben und beenden 
    hWnd = FindWindow(szWindowClass, szTitle); 
    if (hWnd) 
    { 
     // Fokus auf das erste untergeordnete Fenster festlegen 
     // "| 0x00000001" wird verwendet, um alle eigenen Fenster in den Vordergrund zu stellen und 
     // zu aktivieren. 
     SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001)); 
     return 0; 
    } 

    if (!MyRegisterClass(hInstance, szWindowClass)) 
    { 
     return FALSE; 
    } 

    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, 
     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); 

    if (!hWnd) 
    { 
     return FALSE; 
    } 

    // Wenn das Hauptfenster mithilfe von CW_USEDEFAULT erstellt wird, wird die Höhe der Menüleiste (falls 
    // erstellt) nicht berücksichtigt. Daher wird die Größe des Fensters nach dem Erstellen angepasst, 
    // sofern eine Menüleiste vorhanden ist. 
    if (g_hWndMenuBar) 
    { 
     RECT rc; 
     RECT rcMenuBar; 

     GetWindowRect(hWnd, &rc); 
     GetWindowRect(g_hWndMenuBar, &rcMenuBar); 
     rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top); 

     MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE); 
    } 

    ShowWindow(hWnd, nCmdShow); 
    UpdateWindow(hWnd); 


    return TRUE; 
} 

// 
// FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM) 
// 
// ZWECK: Verarbeitet Meldungen vom Hauptfenster. 
// 
// WM_COMMAND - Verarbeiten des Anwendungsmenüs 
// WM_PAINT - Zeichnen des Hauptfensters 
// WM_DESTROY - Beenden-Meldung anzeigen und zurückgeben 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    int wmId, wmEvent; 
    PAINTSTRUCT ps; 
    HDC hdc; 

    static SHACTIVATEINFO s_sai; 

    switch (message) 
    { 
     case WM_COMMAND: 
      wmId = LOWORD(wParam); 
      wmEvent = HIWORD(wParam); 
      // Menüauswahl bearbeiten: 
      switch (wmId) 
      { 
       case IDM_HELP_ABOUT: 
        DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About); 
        break; 
       case IDM_OK: 
        SendMessage (hWnd, WM_CLOSE, 0, 0);    
        break; 
       default: 
        return DefWindowProc(hWnd, message, wParam, lParam); 
      } 
      break; 
     case WM_CREATE: 
      SHMENUBARINFO mbi; 

      memset(&mbi, 0, sizeof(SHMENUBARINFO)); 
      mbi.cbSize  = sizeof(SHMENUBARINFO); 
      mbi.hwndParent = hWnd; 
      mbi.nToolBarId = IDR_MENU; 
      mbi.hInstRes = g_hInst; 

      if (!SHCreateMenuBar(&mbi)) 
      { 
       g_hWndMenuBar = NULL; 
      } 
      else 
      { 
       g_hWndMenuBar = mbi.hwndMB; 
      } 

      // Informationsstruktur für die Aktivierung der Shell initialisieren 
      memset(&s_sai, 0, sizeof (s_sai)); 
      s_sai.cbSize = sizeof (s_sai); 
      break; 
     case WM_PAINT: 
      hdc = BeginPaint(hWnd, &ps); 

      // TODO: Hier den Zeichnungscode hinzufügen. 

      EndPaint(hWnd, &ps); 
      break; 
     case WM_DESTROY: 
      CommandBar_Destroy(g_hWndMenuBar); 
      PostQuitMessage(0); 
      break; 

     case WM_ACTIVATE: 
      // Shell über die Aktivierungsmeldung benachrichtigen 
      SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE); 
      break; 
     case WM_SETTINGCHANGE: 
      SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); 
      break; 

     default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
    } 
    return 0; 
} 

// Meldungshandler für Infofeld. 
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
     case WM_INITDIALOG: 
      { 
       // Erstellen Sie eine Schaltfläche "Fertig", und passen Sie die Größe an. 
       SHINITDLGINFO shidi; 
       shidi.dwMask = SHIDIM_FLAGS; 
       shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU; 
       shidi.hDlg = hDlg; 
       SHInitDialog(&shidi); 
      } 
      return (INT_PTR)TRUE; 

     case WM_COMMAND: 
      if (LOWORD(wParam) == IDOK) 
      { 
       EndDialog(hDlg, LOWORD(wParam)); 
       return TRUE; 
      } 
      break; 

     case WM_CLOSE: 
      EndDialog(hDlg, message); 
      return TRUE; 

    } 
    return (INT_PTR)FALSE; 
} 

相關代碼只是從msdn複製。但是,我收到以下錯誤消息:

unresolved external symbol "recv" referenced in function WinMain 

還有更多的錯誤,但它們都是一樣的。區別在於函數的名稱(例如關機,發送,...)

我試過Win32-Console-Application中的代碼,它運行良好!

有誰知道,爲什麼這個應用程序不起作用?

回答

2

如果你看一下任何Windows CE的socket函數的文檔(例如recv),你會看到它具體規定,LIB文件你需要是ws2.lib

這意味着你需要更換此部分代碼:

// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib 
#pragma comment (lib, "Ws2_32.lib") 
#pragma comment (lib, "Mswsock.lib") 
#pragma comment (lib, "AdvApi32.lib") 

有了這個

#pragma comment (lib, "ws2.lib") 
+0

+1,我跳過該OP正在構建CE應用程序 – rkosegi

+0

謝謝!有用!在搜索庫時,我忘記添加windows ce作爲關鍵字^^ – VRTuomi