Winsock代码产生0xc0000022错误

时间:2016-06-15 19:47:57

标签: c dll winsock winsock2

我最近移植了一个我写的linux应用程序,它广泛使用BSD套接字来进行winsock。代码似乎在linux上运行得很好,并且它在windows上编译得很好,但是当运行可执行文件时,我得到一个带有以下内容的消息框:

The application was unable to start correctly (0xc0000022). Click OK to close the application.

当然,我搜索了有关该错误的内容,并且主要指向了防病毒问题。我收集到应用程序无法以某种方式读取DLL,所以我尝试下载winsock.dll的副本并将其丢弃在我的可执行文件的运行路径中,但无济于事。我还在可执行文件上运行了依赖walker,它给出了很长的错误列表。大多数错误只是警告(例如找到多种CPU类型),但我注意到Error: A circular dependency was detected引起了人们的注意。

正如我所说,代码在linux上按原样运行。这是我的tcp.c:

    #include "tcp.h"

#define BUFSIZE 2048

#if defined(_WIN32)
    #include <winsock2.h>
    typedef int socklen_t;

    struct pollfd {
        SOCKET fd;
        short events;
        short revents;
    };

    #define poll(X,Y,Z) winpoll(X,Y,Z)
    #define POLLOUT 1
    #define POLLIN 0

static int winpoll(struct pollfd *pfd, int ignored, int ignored2) {
    fd_set rfds;
    struct timeval zero = {0};

    int retval;

    FD_ZERO(&rfds);
    FD_SET(pfd->fd, &rfds);

    if (pfd->events == POLLOUT) {
        retval = select(1,NULL,&rfds,NULL,&zero);
    } else {
        retval = select(1,&rfds,NULL,NULL,&zero);
    }

    if (retval < 0) {
        perror("select");
    }

    return retval;
}
#else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/poll.h>
    #include <netinet/tcp.h>
    #include <arpa/inet.h>
    #include <netinet/ip.h>
    #include <netdb.h>
    #include <ifaddrs.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#define BIND(SOCK,ADDR) bind(SOCK,(struct sockaddr*)&(ADDR),sizeof(struct sockaddr_in))
#define CONN(SOCK,ADDR) connect(SOCK,(struct sockaddr*)&(ADDR),sizeof(struct sockaddr_in))

void tcp_wrapup(void) 
{
#if defined(_WIN32)
    WSACleanup();
#endif
}

void tcp_setup(void)
{
#if defined(_WIN32)
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2),&wsaData);
#endif
}

static void set_nonblocking(int fd) 
{
#if defined(_WIN32)
    unsigned long mode = 1; /* non-blocking */
    ioctlsocket(fd, FIONBIO, &mode);
#else
    fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NONBLOCK);
#endif
}

int tcp_server_init(unsigned short port)
{
    int server_sock;
    struct sockaddr_in server_addr = {0};


    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock < 0) { perror("sock"); return -1; }

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    if (BIND(server_sock,server_addr) < 0) { perror("bind"); return -1; }

    set_nonblocking(server_sock);

    if (listen(server_sock, 0) < 0) { perror("listen"); return -1; }

    return server_sock;
}

int tcp_server_poll(int server_sock)
{
    int client_sock;

    client_sock = accept(server_sock,NULL,NULL);
    if (client_sock < 0) {
        return -1;
    }
    return client_sock;
}

int tcp_client_init(unsigned int ip, unsigned short port)
{
    int client_sock;
    struct sockaddr_in client_addr = {0};

    client_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (client_sock < 0) { perror("socket"); return -1; }

    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = htonl(ip);
    client_addr.sin_port = htons(port);

    set_nonblocking(client_sock);

    /* Note: WILL fail, operation in progress, non-blocking sockets wait for
     * handshake. */
    CONN(client_sock,client_addr);

    return client_sock;
}

void tcp_send(int sock, const char *msg) 
{
    int status;
    struct pollfd myfd;
    myfd.fd = sock;
    myfd.events = POLLOUT;

    status = poll(&myfd,1,0);

    if (status == 1) {
        if (send(sock, msg, strlen(msg)+1, 0) < 0) {
            perror("send");
        }
    }
}

int tcp_recv(int sock, char *buf, int max)
{
    int status;
    struct pollfd myfd;
    myfd.fd = sock;
    myfd.events = POLLIN;

    status = poll(&myfd,1,0);

    if (status == 1) {
        int ret;
        if ((ret = recv(sock,buf,max,0)) < 0) {
            return 0;
        }
        return ret;
    }
    return 0;
}

void tcp_close(int sock)
{
#if defined(_WIN32)
    closesocket(sock);
#else
    if (close(sock) < 0) {
        perror("close");
    }
#endif
}

unsigned int tcp_str_to_ip(const char *ip)
{
#if defined(_WIN32)
    int bytes[4];
    sscanf(ip,"%d.%d.%d.%d",&bytes[0],&bytes[1],&bytes[2],&bytes[3]);

    return ntohl(((bytes[0]<<24) & 0xFF) |
                 ((bytes[1]<<16) & 0xFF) | 
                 ((bytes[2]<<8) & 0xFF) |
                 (bytes[3] & 0xFF));
#else
    struct addrinfo *cursor;
    struct addrinfo *server = NULL;
    getaddrinfo(ip,NULL,NULL,&server);

    for (cursor = server; cursor; cursor = cursor->ai_next) {
        if (cursor->ai_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)cursor->ai_addr;
            return ntohl(addr->sin_addr.s_addr);
        }
    }

    return ntohl((unsigned int)inet_addr(ip));
#endif
}

char *tcp_ip_to_str(unsigned int ip)
{
    struct in_addr addr;
    addr.s_addr = htonl(ip);
    return inet_ntoa(addr);
}

unsigned short tcp_get_port(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getpeername(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getpeername");
        return -1;
    }

    return ntohs(addr.sin_port);
}

unsigned int tcp_get_ip(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getpeername(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getpeername");
        return -1;
    }

    return ntohl(addr.sin_addr.s_addr);
}

unsigned short tcp_get_local_port(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getsockname(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getsockname");
        return -1;
    }

    return ntohs(addr.sin_port);
}

unsigned int tcp_get_local_ip(int sock)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(struct sockaddr_in);

    if (getsockname(sock,(struct sockaddr *)&addr,&len) < 0) {
        perror("getsockname");
        return -1;
    }

    return ntohl(addr.sin_addr.s_addr);
}

我的tcp.h标题:

#ifndef _TCP_H
#define _TCP_H

typedef int TCP_Socket;

/* <0 means no connection, try again */
TCP_Socket tcp_server_init(unsigned short);
TCP_Socket tcp_server_poll(TCP_Socket);
TCP_Socket tcp_client_init(unsigned int, unsigned short); 

void tcp_send(TCP_Socket, const char *); 
int tcp_recv(TCP_Socket, char *, int); /* 0 = no data */

void tcp_close(TCP_Socket);

unsigned int tcp_str_to_ip(const char *);
char *tcp_ip_to_str(unsigned int); /* in static buf */

unsigned short tcp_get_port(TCP_Socket);
unsigned int tcp_get_ip(TCP_Socket);
unsigned short tcp_get_local_port(TCP_Socket);
unsigned int tcp_get_local_ip(TCP_Socket);

/* Windows needs wrapup code. */
void tcp_wrapup(void);
void tcp_setup(void);
#endif /* _TCP_H */

对于命令行,windows版本只是将-lwsock32添加到linux版本使用的命令的末尾。知道如何让我的代码工作吗?

注意

我尝试使用调试模式进行编译,它仍然提供相同的错误代码。我使用break main运行gdb,在它甚至可以击中主断点之前它崩溃了During startup program exited with code 0xc0000022。这让我相信它可能是代码之外的问题?或者可能是代码的权限?

0 个答案:

没有答案