2015-07-02 4 views
1

Я пытаюсь изучить программирование Berkeley Socket, но я действительно застрял здесь: У меня есть ошибка 10038 как моей серверной, так и клиентской программы, в соответствии с MSDN это означает: «операция была предпринята для чего-то, что не является сокетом ", но мой сокет - это« сокет ». Вот код клиента/сервера:Не удалось исправить ошибку 10038 WSAENOTSOCK

мой клиент:

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 

#define BUFFSIZE 32 

void DieWithError(char *errorMessage); 

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

    int sock, bytesLen; 
    struct sockaddr_in servAddr; 
    unsigned short servPort =13; 
    char * servIP; 
    char buff[BUFFSIZE+1]; 
    WSADATA wsaData; 

    if(argc == 2){ 
     servIP = argv[1]; 
    } 

    if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){ 
     puts("ERROR WSA"); 
    } 

    if(sock=socket(AF_INET, SOCK_STREAM, 0) < 0){ 
     puts("ERROR socket"); 
    } 

    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port  = htons(servPort); 
    servAddr.sin_addr.s_addr = inet_addr(&servIP); 

    if(connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)<0)){ 
     DieWithError("connect Error"); 
    } 

    while(bytesLen=read(sock, buff, BUFFSIZE)){ 
     buff[bytesLen]= '\n'; 
    } 

    printf("Heure : %s",buff); 

    closesocket(sock); 
    WSACleanup(); 

    return 0; 
} 

void DieWithError(char *errorMessage) 
{ 
    fprintf(stderr,"%s: %d\n", 
    errorMessage, WSAGetLastError()); 
    exit(1); 
} 

и мой север:

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 
#include <time.h> 
#include <stdlib.h> 


#define MAXLINE 32 

void DieWithError(char *errorMessage); 

int main(){ 

    int sock, sockc; 
    struct sockaddr_in servAddr; 
    unsigned short servPort =13; 
    time_t ticks; 
    WSADATA wsaData; 
    char buff[MAXLINE]; 
    char * servIP; 

    if(WSAStartup(MAKEWORD(2,0), &wsaData) != 0){ 
     puts("ERROR WSA"); 
    } 

    if(sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0){ 
     puts("ERROR socket"); 
    } 
    servIP = "10.1.1.3"; 
    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port  = htons(servPort); 
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    if(bind(sock,(struct sockaddr *)&servAddr, sizeof(servAddr) < 0)){ 
     DieWithError("bind)()"); 
    } 

    if(listen(sock,MAXQUEUE) < 0){ 
     DieWithError("listen()"); 
    } 

    while(1){ 

     sockc = accept(sock, (struct sockaddr *)NULL, NULL); 
     ticks = time(NULL); 
     snprintf(buff,sizeof(buff),"%s",ctime(&ticks)); 

     write(buff, sizeof(buff), MAXLINE); 
    } 

    return 0; 
} 

void DieWithError(char *errorMessage) 
{ 
    fprintf(stderr,"%s: %d\n", 
     errorMessage, WSAGetLastError()); 
    exit(1); 
} 

каждый запуск у меня есть 10038 на connect() функции клиента и 10038 на функция bind() на сервере.

СПАСИБО за вашу помощь.

ответ

1

В отличие от других платформ, Windows не использует дескрипторы файлов для представления сокетов. Он использует реальные объекты ядра. Другие платформы используют int для представления открытых файловых дескрипторов и, следовательно, для представления сокетов. Вместо этого Windows использует тип SOCKET, который является typedef для UINT_PTR (unsigned int в 32bit, unsigned __int64 в 64 бит), поэтому он может размещать дескрипторы объектов. Функция socket() на Windows возвращает INVALID_SOCKET (то есть (SOCKET)(~0)) при ошибке, в то время как другие платформы возвращают (int)-1. Вам нужно убедиться, что вы учитываете это, чтобы не разрезать/усекать законные дескрипторы сокетов в Windows.

Когда ваш клиент звонит inet_addr(), он отправляет char**, где ожидается char*. Ваш компилятор должен был сообщить об ошибке.

Поскольку сокеты не представлены в качестве дескрипторов файлов в Windows, вы не можете использовать функции read() и write() с сокетами Windows. Вместо этого вы должны использовать функции recv()/WSARecv() и send()/WSASend(). И вам нужно обработать случай, когда функции могут возвращать SOCKET_ERROR (-1) при ошибке.

Попробуйте что-то больше, как это вместо:

клиент:

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 

#define BUFFSIZE 32 

void DieWithErrorCode(char *errorMessage, int errCode); 
void DieWithError(char *errorMessage, int *errCode = NULL); 

int main(int argc, char* argv[]) 
{ 
    SOCKET sock; 
    int ret; 
    struct sockaddr_in servAddr; 
    unsigned short servPort = 13; 
    char *servIP; 
    char buff[BUFFSIZE]; 
    WSADATA wsaData; 

    if (argc != 2) { 
     DieWithErrorCode("ERROR argc", WSAEINVAL); 
    } 
    servIP = argv[1]; 

    ret = WSAStartup(MAKEWORD(2,0), &wsaData); 
    if (ret != 0) { 
     DieWithErrorCode("ERROR WSAStartup", ret); 
    } 

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sock == INVALID_SOCKET) { 
     DieWithError("ERROR socket"); 
    } 

    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(servPort); 
    servAddr.sin_addr.s_addr = inet_addr(servIP); 
    if (servAddr.sin_addr.s_addr == INET_NONE) { 
     DieWithErrorCode("ERROR inet_addr", WSAEINVAL); 
    } 

    if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { 
     DieWithError("ERROR connect"); 
    } 

    while(1) { 
     ret = recv(sock, buff, BUFFSIZE, 0); 
     if (ret == SOCKET_ERROR) { 
      DieWithError("ERROR recv"); 
     } 

     if (ret == 0) { 
      fprintf(stderr, "disconnected\n"); 
      break; 
     } 

     printf("Heure : %.*s\n", ret, buff); 
    } 

    closesocket(sock); 
    WSACleanup(); 

    return 0; 
} 

void DieWithErrorCode(char *errorMessage, int errCode) 
{ 
    fprintf(stderr, "%s: %d\n", errorMessage, errCode); 
    exit(1); 
} 

void DieWithError(char *errorMessage) 
{ 
    DieWithErrorCode(errorMessage, WSAGetLastError()); 
} 

сервер:

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 
#include <time.h> 
#include <stdlib.h> 

#define MAXLINE 32 

void DieWithErrorCode(char *errorMessage, int errCode); 
void DieWithError(char *errorMessage); 

int main() 
{ 
    SOCKET sock, sockc; 
    struct sockaddr_in servAddr; 
    unsigned short servPort = 13; 
    time_t ticks; 
    WSADATA wsaData; 
    char buff[MAXLINE]; 
    int ret, buflen; 

    ret = WSAStartup(MAKEWORD(2,0), &wsaData); 
    if (ret != 0) { 
     DieWithErrorCode("ERROR WSA", ret); 
    } 

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sock == INVALID_SOCKET) { 
     DieWithError("ERROR socket"); 
    } 

    memset(&servAddr, 0, sizeof(servAddr)); 
    servAddr.sin_family = AF_INET; 
    servAddr.sin_port = htons(servPort); 
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY); 

    if (bind(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) { 
     DieWithError("ERROR bind"); 
    } 

    if (listen(sock, MAXQUEUE) == SOCKET_ERROR) { 
     DieWithError("ERROR listen"); 
    } 

    while(1) { 
     sockc = accept(sock, NULL, NULL); 
     if (sockc == INVALID_SOCKET) { 
      DieWithError("ERROR accept"); 
     } 

     ticks = time(NULL); 
     buflen = snprintf(buff, sizeof(buff), "%s", ctime(&ticks)); 
     if (send(sockc, buff, buflen, 0) == SOCKET_ERROR) { 
      fprintf(stderr, "ERROR send: %d\n", WSAGetLastError()); 
     } 

     closesocket(sockc); 
    } 

    closesocket(sock); 
    WSACleanup(); 

    return 0; 
} 

void DieWithErrorCode(char *errorMessage, int errCode) 
{ 
    fprintf(stderr,"%s: %d\n", errorMessage, errCode); 
    exit(1); 
} 

void DieWithError(char *errorMessage) 
{ 
    DieWithErrorCode(char *errorMessage, WSAGetLastError()); 
} 
+0

Спасибо за вашу помощь, очень полезно. – Thal

Смежные вопросы