none
WIN7 socket失败 RRS feed

  • 问题

  • 在WIN7 x64下创建socket时发生一个很诡异的现象,创建一个TCP 的SOCKET总是失败,但是创建UDP会成功,如果在创建UDP后再创建TCP,那么TCP的socket也会成功,求助各位。这是为什么?怎么解决这个问题。这种现象导致一些软件不能用

    //============================================================================
    // Name        : wtxregd.cpp
    // Author      : CHENQ
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C, Ansi-style
    //============================================================================
    #include "stdafx.h"
    
    #define WIN7_SOCKET_MYDEBUG
    
    static int WSAUnInit();
    static int WSAInit()
    {
        WSADATA   data;
        int ret = WSAStartup(0x0202, &data);
        if (ret != 0)
        {
        	WSAUnInit();
            printf ("Init Winsock2 Failed!\n");
            return __LINE__;
        }
        return 0;
    }
    
    int WSAUnInit()
    {
        return WSACleanup();
    }
    
    int Server(int port)
    {
    	WSAInit();
        SOCKET mListener = socket(AF_INET, SOCK_STREAM, 0);
    
    #ifdef WIN7_SOCKET_MYDEBUG
        SOCKET mUdpsock = socket(AF_INET, SOCK_DGRAM, 0);
        SOCKET mListener0 = socket(AF_INET, SOCK_STREAM, 0);
    #endif
    
        if (mListener == INVALID_SOCKET)
        {
        	printf ("creat listen socket failed, errno=%d\n", WSAGetLastError());
        }
    #ifdef WIN7_SOCKET_MYDEBUG
        if (mUdpsock == INVALID_SOCKET)
        {
        	printf ("creat listen Udp socket failed, errno=%d\n", WSAGetLastError());
        }
        if (mListener0 == INVALID_SOCKET)
        {
        	printf ("creat listen socket0 failed, errno=%d\n", WSAGetLastError());
        }
    #endif
        //JUST for debug
        return __LINE__;
    
        int val;
        {
        	// Settings on socket
        	BOOL  sopt = TRUE;
        	setsockopt(mListener, IPPROTO_TCP, TCP_NODELAY,
        			(char *)&sopt, sizeof(BOOL));
        	setsockopt(mListener, SOL_SOCKET, SO_DONTLINGER,
        			(char *)&sopt, sizeof(BOOL));
    
        	// Bind socket and listen
        	SOCKADDR_IN  addr;
        	memset(&addr, 0, sizeof(SOCKADDR_IN));
        	addr.sin_family      = AF_INET;
        	addr.sin_addr.s_addr = htonl(INADDR_ANY);
        	addr.sin_port        = htons(port);
        	val = bind(mListener, (struct sockaddr*) &addr, sizeof(addr));
    
        	if (val != 0)
        	{
        		printf ("Bind port failed, errno=%d\n", WSAGetLastError());
        		closesocket(mListener);
        		WSAUnInit();
        		return __LINE__;
        	}
        }
    
        {
        	// Put the socket into the listening status
        	val = listen(mListener, SOMAXCONN);
        	if (val < 0)
        	{
        		printf ("Listen failed, errno=%d\n", WSAGetLastError());
        	}
        }
        SOCKADDR_IN saddr;
        int len = 0;
        SOCKET mAccepted = accept(mListener, (SOCKADDR *)&saddr, &len);
        if (mAccepted == INVALID_SOCKET)
        {
        	closesocket(mListener);
        	WSAUnInit();
        	printf ("accept failed, errno=%d\n", WSAGetLastError());
        	return __LINE__;
        }
    #if 0
        SOCKET mAccepted = accepted;
        // Settings on socket
        BOOL sopt = TRUE;
        setsockopt(mAccepted, IPPROTO_TCP, TCP_NODELAY,
        		(char *)&sopt, sizeof(BOOL));
        setsockopt(mAccepted, SOL_SOCKET, SO_DONTLINGER,
        		(char *)&sopt, sizeof(BOOL));
    #endif
        char szBuf[512];
        for (;;)
        {
        	FD_SET rSet;
        	FD_ZERO(&rSet);
        	FD_SET(mAccepted ,&rSet);
        	timeval val = {0};
        	select(mAccepted+1, &rSet, NULL, NULL, &val);
        	if (FD_ISSET(mAccepted, &rSet))
        	{
        		memset (szBuf, 0, sizeof(szBuf));
        		int ret = recv(mAccepted, szBuf, sizeof(szBuf), 0);
        		if (ret > 0)
        			printf ("Recv::%s\n", szBuf);
        		if (strcmp(szBuf, "quit")==0)
        			break;
        	}
        }
    
    
    #if 0
        SOCKET socket( IN int af, IN int type, IN int protocol );
        af (AF_INET) ARPA因特网协议(UNIX网络套接字);
        		type——SOCK_STREAM 流式套接字TCP;SOCK_DGRAM 数据报套接字UCP
        		protocol——0为默认值,IPPROTO_TCP IP网的TCP协议
    
        int setsockopt(IN SOCKET s, IN int level, IN int optname, IN const char FAR * optval, IN int optlen);
        ——设置套接口的选项
        // TCP_NODELAY选项禁止Nagle算法
        //SO_DONTLINER BOOL 不要因为数据未发送就阻塞关闭操作。相当于将SO_LINGER的 l_onoff 元素置为零
    
        int bind(IN SOCKET s,IN const struct sockaddr FAR * name,IN int namelen);
        ——绑定socket和地址和端口监听因特网上的任意ip地址接入 INADDR_ANY
    
        int listen( IN SOCKET s,IN int backlog);
        ——backlog队列中可以容纳的未处理连接的最大数目限制
        ——listen函数为服务器程序创建一个队列来保存未处理的请求
    #endif
        closesocket(mAccepted);
        closesocket(mListener);
    	return WSAUnInit();
    }
    
    int main(void)
    {
    	Server(30232);
    	return EXIT_SUCCESS;
    }

    运行结果是

    creat listen socket failed, errno=0

    说明    SOCKET mUdpsock = socket(AF_INET, SOCK_DGRAM, 0);
        SOCKET mListener0 = socket(AF_INET, SOCK_STREAM, 0);都成功了

    外部现象见我之前发的帖子:

    http://answers.microsoft.com/zh-hans/windows/forum/windows_7-networking/ipv4%E5%B7%A5%E4%BD%9C%E4%B8%8D%E6%AD%A3%E5%B8%B8/984225a3-8dfb-47e1-8d0b-a31c2bd69b99

    2012年3月11日 8:50

答案

  • SOCKET mListener = socket(AF_INET, SOCK_STREAM, 0);
    if(INVALID_SOCKET == mListener)
    {
      // error call WSAGetLastError();
    }

    #ifdef WIN7_SOCKET_MYDEBUG
        SOCKET mUdpsock
    = socket(AF_INET, SOCK_DGRAM, 0);
        SOCKET mListener0
    = socket(AF_INET, SOCK_STREAM, 0);
    #endif


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Helen Zhao 2012年3月19日 1:20
    2012年3月11日 22:32
    版主
  • 一般的,如果一个函数调用失败,应该紧接着调用GetLastError得到错误码,而不是再调用其它的函数,因为调用其它的函数,这个error code可能会被改写。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已建议为答案 Helen Zhao 2012年3月13日 2:57
    • 取消建议作为答案 study_c 2012年3月13日 14:08
    • 已标记为答案 Helen Zhao 2012年3月19日 1:20
    2012年3月13日 1:53
    版主
  • SOCKET mListener = socket(AF_INET, SOCK_STREAM, 0);
    if (mListener == INVALID_SOCKET)
        {
        	printf ("creat listen socket failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
    #ifdef WIN7_SOCKET_MYDEBUG
        SOCKET mUdpsock = socket(AF_INET, SOCK_DGRAM, 0);
        if (mUdpsock == INVALID_SOCKET)
        {
        	printf ("creat listen Udp socket failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
        SOCKET mListener0 = socket(AF_INET, SOCK_STREAM, 0);
        
        if (mListener0 == INVALID_SOCKET)
        {
        	printf ("creat listen socket0 failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
    #endif


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Helen Zhao 2012年3月19日 1:21
    2012年3月16日 5:10
    版主

全部回复

  • SOCKET mListener = socket(AF_INET, SOCK_STREAM, 0);
    if(INVALID_SOCKET == mListener)
    {
      // error call WSAGetLastError();
    }

    #ifdef WIN7_SOCKET_MYDEBUG
        SOCKET mUdpsock
    = socket(AF_INET, SOCK_DGRAM, 0);
        SOCKET mListener0
    = socket(AF_INET, SOCK_STREAM, 0);
    #endif


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Helen Zhao 2012年3月19日 1:20
    2012年3月11日 22:32
    版主
  • what do you mean? 什么意思? errno=0 & mListener=INVALID_SOCKET
    2012年3月12日 15:49
  • 一般的,如果一个函数调用失败,应该紧接着调用GetLastError得到错误码,而不是再调用其它的函数,因为调用其它的函数,这个error code可能会被改写。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已建议为答案 Helen Zhao 2012年3月13日 2:57
    • 取消建议作为答案 study_c 2012年3月13日 14:08
    • 已标记为答案 Helen Zhao 2012年3月19日 1:20
    2012年3月13日 1:53
    版主
  • 如您所说,已经修改代码为:

        if (mListener == INVALID_SOCKET)
        {
         int errorno = WSAGetLastError();
         printf ("creat listen socket failed, errno=%d\n", errorno);
        }

    运行结果依旧,错误号依旧是0,还是无法定位原因. 感谢您提的宝贵意见。

    2012年3月13日 14:08
  • 请将您完整的代码贴出来看看

    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    2012年3月13日 15:09
    版主
  • 我贴出来的就是完整代码
    • 已编辑 study_c 2012年3月14日 13:29
    2012年3月14日 13:29
  • SOCKET mListener = socket(AF_INET, SOCK_STREAM, 0);
    if (mListener == INVALID_SOCKET)
        {
        	printf ("creat listen socket failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
    #ifdef WIN7_SOCKET_MYDEBUG
        SOCKET mUdpsock = socket(AF_INET, SOCK_DGRAM, 0);
        if (mUdpsock == INVALID_SOCKET)
        {
        	printf ("creat listen Udp socket failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
        SOCKET mListener0 = socket(AF_INET, SOCK_STREAM, 0);
        
        if (mListener0 == INVALID_SOCKET)
        {
        	printf ("creat listen socket0 failed, errno=%d\n", WSAGetLastError());
             return -1;
        }
    #endif


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.

    • 已标记为答案 Helen Zhao 2012年3月19日 1:21
    2012年3月16日 5:10
    版主