2016-06-03 7 views
-1

Ich verwende Winsock, um eine Verbindung zum Remote-Server herzustellen. Ich war erfolgreich beim Verbinden des Sockets, aber wenn ich versuche, Socket-Details mit Select zu bekommen, heißt es, Socket existiere nicht (WSAENOTSOCK).Windows c socket: select() gibt WSAENOTSOCK-Fehler

NB: Ich Ausführen dieses Code als Visual Studio win Konsolenanwendung und mein Betriebssystem ist Windows 8.

Mein Code (Code Angenommen Ausführung beginnt run_client Funktion und Test-Struktur alle Möglichkeiten hat). Außerdem sind Funktionen in verschiedenen Dateien, so muss ich mehrmals

#define _CRT_SECURE_DEPRECATE_MEMORY 
#define _CRT_SECURE_NO_WARNINGS 
#define _WINSOCK_DEPRECATED_NO_WARNINGS 

#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <io.h> 
#include <signal.h> 
#include <sys/types.h> 
#include <Winsock2.h> 
#include <memory.h> 
#include <WS2tcpip.h> 

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

int run_client(struct test * test) 
{ 
    int startup; 
    int result = 0; 
    fd_set read_set, write_set, excep_fd; 
    struct timeval now; 
    struct timeval* timeout = NULL; 
    struct iperf_stream *sp; 

    FD_ZERO(&excep_fd); 

    if (soc_connect(test) < 0) 
     return -1; 

    printf("Run client : success in making socket\n"); 

    memcpy(&read_set, &test->read_set, sizeof(fd_set)); 
    memcpy(&write_set, &test->write_set, sizeof(fd_set)); 

    int iResult; 
    WSADATA wsaData; 

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if (iResult != 0) { 
     printf("WSAStartup failed: %d\n", iResult); 
     return -1; 
    } 

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { 
     printf("Could not find a usable version of Winsock.dll\n"); 
     WSACleanup(); 
     return -1; 
    } 
    else 
    { 
     printf("The Winsock 2.2 dll was found okay\n"); 
    } 


    struct timeval tv; 
    tv.tv_sec = 1; 
    tv.tv_usec = 0; 

    result = select(test->ctrl_sck + 1, &read_set, 0, 0, &tv); 

    if (SOCKET_ERROR == result) 
    { 
     switch (WSAGetLastError()) 
     { 
      case WSANOTINITIALISED: 
       printf("select_result error : WSANOTINITIALISED\n"); 
       break; 
      case WSAEFAULT: 
       printf("select_result error : WSAEFAULT\n"); 
       break; 
      case WSAENETDOWN: 
       printf("select_result error : WSAENETDOWN\n"); 
       break; 
      case WSAEINTR: 
       printf("select_result error : WSAEINTR\n"); 
       break; 
      case WSAEINPROGRESS: 
       printf("select_result error : WSAEINPROGRESS\n"); 
       break; 
      case WSAENOTSOCK: 
       printf("select_result error : WSAENOTSOCK\n"); 
       break; 
      default: 
       printf("select_result errors : %d\n", WSAGetLastError()); 
       break; 
     } 
     i_errno = WSAGetLastError(); 
     closesocket(test->ctrl_sck); 
     WSACleanup(); 
     return -1; 
    } 
    else if (result == 0) 
    { 
     printf("select_result : timeout : %d\n", result); 
     WSACleanup(); 
     return -1; 
    } 
    else 
    { 
     WSACleanup(); 
    } 
} 

int soc_connect(struct test *test) 
{ 
    FD_ZERO(&test->read_set); 
    FD_ZERO(&test->write_set); 

    printf("Making cookie\n"); 

    make_cookie(test->cookie); 

    printf("Success in Making cookie\n"); 

    /* Create and connect the control channel */ 
    if (test->ctrl_sck < 0) 
    { 
     test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, 0, test->server_hostname, test->server_port); 
    } 

    if (test->ctrl_sck < 0) { 
     i_errno = IECONNECT; 
     return -1; 
    } 

    FD_SET(test->ctrl_sck, &test->read_set); 
    return 0; 
} 

void make_cookie(char *cookie) 
{ 
    static int randomized = 0; 
    char hostname[500]; 
    struct timeval tv; 
    char temp[1000]; 

    if (! randomized) 
     srand((int) time(0)^getpid()); 

    (void) gethostname(hostname, sizeof(hostname)); 
    (void) gettimeofday(&tv, 0); 
    (void) snprintf(temp, sizeof(temp), "%s.%ld.%06ld.%08lx%08lx.%s", hostname, (unsigned long int) tv.tv_sec, (unsigned long int) tv.tv_usec, (unsigned long int) rand(), (unsigned long int) rand(), "123456789"); 

    memcpy(cookie, temp, 36); 
    cookie[36] = '\0'; 
} 

int netdial(int domain, int proto, char *local, int local_port, char *server, int port) 
{ 
    struct addrinfo hints, *local_res = NULL, *server_res = NULL; 
    int s; 

    WSADATA wsaData; 
    int iResult; 
    INT iRetval; 

    char port_str[6]; 
    snprintf(port_str, 6, "%d", port); 

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); 
    if (iResult != 0) { 
     printf("WSAStartup failed: %d\n", iResult); 
     return -1; 
    } 

    if (local) { 
     memset(&hints, 0, sizeof(hints)); 
     hints.ai_family = domain; 
     hints.ai_socktype = proto; 
     if (getaddrinfo(local, port_str, &hints, &local_res) != 0) 
     { 
      WSACleanup(); 
      printf("Net dial : 0\n"); 
      return -1; 
     } 
    } 

    ZeroMemory(&hints, sizeof(hints)); 
    hints.ai_family = domain; 
    hints.ai_socktype = proto; 
    hints.ai_protocol = IPPROTO_TCP; 
    if (getaddrinfo(server, port_str, &hints, &server_res) != 0) 
    { 
     WSACleanup(); 
     return -1; 
    } 


    s = socket(server_res->ai_family, server_res->ai_socktype, server_res->ai_protocol); 
    if (s == INVALID_SOCKET) { 
     if (local) 
     { 
      if (local_res != NULL) 
       freeaddrinfo(local_res); 
     } 
     freeaddrinfo(server_res); 
     WSACleanup(); 
     return -1; 
    } 

    printf("Socket created\n"); 

    if (local) { 
     if (local_port) { 
      printf("Net dial : 3\n"); 
      struct sockaddr_in *lcladdr; 
      lcladdr = (struct sockaddr_in *)local_res->ai_addr; 
      lcladdr->sin_port = htons(local_port); 
      local_res->ai_addr = (struct sockaddr *)lcladdr; 
     } 

     if (bind(s, (struct sockaddr *) local_res->ai_addr, local_res->ai_addrlen) < 0) { 
      _close(s); 
      WSACleanup(); 
      freeaddrinfo(local_res); 
      freeaddrinfo(server_res); 
      printf("Net dial : 4\n"); 
       return -1; 
     } 
     freeaddrinfo(local_res); 
    } 

    iResult = connect(s, server_res->ai_addr, (int)server_res->ai_addrlen); 
    if (iResult == SOCKET_ERROR) { 
     closesocket(s); 
     s = INVALID_SOCKET; 
    } 

    freeaddrinfo(server_res); 

    if (s == INVALID_SOCKET) { 
     WSACleanup(); 
     return -1; 
    } 

    printf("Socket connected\n"); 

    WSACleanup(); 
    return s; 
} 

Ausgabe

Making cookie 
Success in Making cookie 
Socket created 
Socket connected 
Run client : success in making socket 
The Winsock 2.2 dll was found okay 
select_result errors : WSAENOTSOCK 

ich gegoogelt haben dieses Problem nennen WSAStartup und versucht, viele Lösungen, aber ich kann keine Lösung finden für meine. Kann bitte einen bitte aushelfen.

+1

Sind Sie sicher, dass die Windows-Version der fd_set-Struktur mit memcpy() kompatibel ist? Vielleicht solltest du eigentlich eine Liste von Sockets in deiner 'test' Struktur behalten und das fd_set jedes Mal aus der Liste füllen ... – Medinoc

+2

Warum rufst du' WSAStartup() 'mehrmals an? Und 'WSACleanup()'? Diese sollten nur einmal pro Prozess aufgerufen werden. – EJP

+0

@EJP Funktionen sind in verschiedenen c-Dateien. Also, ich brauche. Tut mir leid, dass ich nicht erwähnt habe. –

Antwort

3

Funktionen sind in verschiedenen Dateien, so muss ich mehrmals

Nein, haben Sie nicht nennen WSAStartup. Dies ist eine Fabrikation Ihrerseits. Sie müssen einmal am Anfang des Prozesses WSAStartup() und einmal am Ende des Prozesses WSACleanup() aufrufen.

Ich kann mir nicht vorstellen, wie oder wo Sie diese Idee haben, aber es ist falsch. Winsock weiß nicht, wie viele C-Dateien Sie haben.

+0

Entschuldigung. Ich weiß es nicht. Danke für den Punkt. Ich habe WSAStartup() einmal probiert, zu Beginn des Prozesses. Jetzt wähle das() Ergebnis von WSAENOTSOCK auf Null geändert. Ich habe versucht, Timeout auf 10 Sekunden zu erhöhen, dann werde ich auch nach 10 Sekunden Null. Hast du eine Ahnung davon? –

+0

Danke EJP. Das war das Problem. –

+1

Wenn 'select()' 0 zurückgibt, bedeutet dies, dass die Zeitüberschreitung abgelaufen ist. Also, egal in welchem ​​Zustand du wartest, wird offensichtlich nicht zufriedengestellt. –