服务端, 开启服务的代码:
m_socksvr = socket(AF_INET, SOCK_STREAM, 0);
if ((m_socksvr == INVALID_SOCKET) || (NULL == m_socksvr))
{
AfxMessageBox("Create socket");
return; 
}

int ret = WSAAsyncSelect(m_socksvr, m_hWnd, WM_SOCKET, 
             FD_READ | FD_WRITE | FD_ACCEPT);
if (SOCKET_ERROR == ret)
{
AfxMessageBox("Select");
closesocket(m_socksvr);
m_socksvr = NULL;
return;
}

struct sockaddr_in svraddr;
hostent *hostaddr;
char hostnm[255];
gethostname(hostnm, 255);
hostaddr = gethostbyname(hostnm);
svraddr.sin_family = AF_INET;
svraddr.sin_port = 10001;
svraddr.sin_addr.S_un.S_addr = *((unsigned long *)hostaddr->h_addr_list[0]);
memset(svraddr.sin_zero, 0, 8);

ret = bind(m_socksvr, (sockaddr *)&svraddr, sizeof(svraddr));
if ((ret == SOCKET_ERROR) || (0 != ret))
{
AfxMessageBox("bind");
closesocket(m_socksvr);
m_socksvr = NULL;
return;
} ret = listen(m_socksvr, 5);
if ((SOCKET_ERROR == ret) || (0 != ret))
{
AfxMessageBox("listen");
closesocket(m_socksvr);
m_socksvr = NULL;
return;
}
在消息处理函数里的代码:
char *buf = NULL;
switch (lp)
{
case FD_ACCEPT:
m_csock = accept(m_socksvr, 
(sockaddr FAR *)&caddr, 
&addlen);
if ((NULL == m_csock) || (SOCKET_ERROR == m_csock))
{
AfxMessageBox("Accept fail");
m_csock = NULL;
}
break; case FD_READ:
buf = (char *)malloc(1024);
recv(m_csock, buf, 1024, 0);
free(buf);
buf = NULL;
break; case FD_WRITE:
send(m_csock, (char *)wp, strlen((char *)wp), 0);
break; }
return 0;
客户端,连接代码:
m_sock = socket(AF_INET, SOCK_STREAM, 0);
if ((NULL == m_sock) || (INVALID_SOCKET == m_sock))
{
AfxMessageBox("Create socket fail");
m_sock = NULL;
return;
}
int ret = WSAAsyncSelect(m_sock, m_hWnd, WM_SOCKET, 
                     FD_READ | FD_WRITE);
if ((0 != ret) || (SOCKET_ERROR == ret))
{
AfxMessageBox("select fail");
closesocket(m_sock);
m_sock = NULL;
return;
}
struct sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_addr.S_un.S_addr = inet_addr((char FAR *)"192.168.0.6");//服务器IP地址
saddr.sin_port = 10001;
memset(saddr.sin_zero, 0, 8);
ret = connect(m_sock, (sockaddr *)&saddr, sizeof(saddr));
if ((0 != ret) || (SOCKET_ERROR == ret))
{
AfxMessageBox("connect fail");
closesocket(m_sock);
}
为什么会连接不上呢? 报出的错误号是:WSAEWOULDBLOCK(10035)
看了好多书和示例程序,都这样做的,为什么我的这段程序就不行。
郁闷好久了,求教各位大虾,请不吝赐教。
若觉得分不够,可以再开贴加分!

解决方案 »

  1.   

    客户端代码:int ret = WSAAsyncSelect(m_sock, m_hWnd, WM_SOCKET, FD_READ | FD_WRITE);加上FD_CONNECT试试还有saddr.sin_port =htons(10001);  //使用htons()
      

  2.   

    worldcup(), 谢谢您对我的问题的关注,我照您说的试过了,依然是没能连接啊。这个问题有这么困难吗? 我可是照着这示例程序和书本做的啊。。大虾们,请帮帮我吧!
      

  3.   

    我刚刚开始看这个,不知道是不是因为你没有初始化WinSock库?
      

  4.   

    在调用SOCKET函数前要调用WSAStartup(),不知你调用没有,
    结束时要WSACleanup()
      

  5.   

    那些调用我都有做啊, 在OnInitDialog里面:
    WSADATA wsaData;
    int ret = WSAStartup(0x202, &wsaData);
    if (0 != ret)
    {
         AfxMessageBox("startup fail");
         return FALSE;
    }
    if (wsaData.wVersion != 0x202)
    {
        AfxMessageBox("version wrong!");
        return FALSE;
    }
    在Dialog的OnDestroy里面:  WSACleanup();
    包含的头文件是<winsock2.h> (在StdAfx.h中包含)
    引用的库文件是 ws2_32.lib
    大虾们,帮忙看看,问题到底出在什么地方啊?郁闷啊!
      

  6.   

    我做服务/客户端结构用的是MFC的CAsyncSocket类,很简单的
      

  7.   

    WSAEWOULDBLOCK (10035) Resource temporarily unavailable. 此错误由在非阻塞套接字上不能立即完成的操作返回,例如,当套接字上没有排队数据可读时调用了recv()函数。此错误不是严重错误,相应操作应该稍后重试。对于在非阻塞SOCK_STREAM套接字上调用connect()函数来说,报告WSAEWOULDBLOCK是正常的,因为建立一个连接必须花费一些时间。
      

  8.   

    正如楼上所说,这个返回代码是正常的,你可以在connect之后sleep一下,然后再WSAGetLastError试试看
      

  9.   

    非阻塞模式中的各个函数几乎都不会立即成功返回(一般是通过事件来得到结果)。你用了Sleep之后那个函数调用成功了就好了。
      

  10.   

    实际上这不应该算作一个错误,它是Socket提醒我们,由于你使用了非阻塞Socket方式,所以(连接)操作需要时间,不能瞬间建立。你可以在Connect后Sleep(0),然后不停的GetLastError查看Socket返回的结果,直到成功为止。
        也可以在Connect()调用之后等待CAsyncSocket::OnConnect()事件被触发,这是推荐的方法,CAsyncSocket::OnConnect()是要表明Socket要么连接成功了,要么连接彻底失败了。至此,我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了,还是失败了。
      

  11.   

    你将
    int ret = WSAAsyncSelect(m_socksvr, m_hWnd, WM_SOCKET, 
                 FD_READ | FD_WRITE | FD_ACCEPT);
    if (SOCKET_ERROR == ret)
    {
    AfxMessageBox("Select");
    closesocket(m_socksvr);
    m_socksvr = NULL;
    return;
    }
    移到bind后面看一下
      

  12.   

    按照kobee() 大虾的意思,我在connect之后加了一条Sleep(0)语句。然后运行情况是:
      accept立即返回错误,connect也立即返回错误。
      之后就不停得弹出“Accept fail”对话框(如楼顶源码), 
      按热启动键都没反映(WIN2000),只好关电源了。
    其实这段代码小弟是基本照搬了一个示例程序的代码,所不同的是示例中没有用MFC窗体,我懒得写API去做界面了,就这些不一样,怎么他那个就行,我这个却不行?
    郁闷,尴尬。。
    请各位大虾多多赐教啊,分数的事好说!
      

  13.   

    在connect()和accept()后都加上Sleep(1000)再试试!
      

  14.   

    客户端不要WSAAsyncSelect,用blocking 方式试试我就是看了你的例子用堵塞方式弄对了
      

  15.   

    在connect()和accept()后都加上Sleep(50)再试
      

  16.   

    我试过Sleep(50) 和 Sleep(1000) 了,依然如故啊。太不可理喻了,救命啊! 我的头要爆了。。
      

  17.   

    客户端connect是立即返回错误的,服务器段的accept也立即返回错误,但是他为什么会执行很多次accept呢?难道客户端连接失败后服务端会不停地收到FD_ACCEPT消息吗?
      

  18.   

    阻塞模式我也试过了,就是在服务端开一个线程来ACCEPTUINT AcceptProc(VOID *pParam)
    {
    CSockSvrDlg *pDlg = (CSockSvrDlg *)pParam;
    pDlg->m_csock = accept(pDlg->m_socksvr, 
        (sockaddr FAR *)&caddr, 
                  &addlen);
    if ((NULL == pDlg->m_csock) || (SOCKET_ERROR == pDlg->m_csock))
    {
    AfxMessageBox("Accept fail");
    pDlg->m_csock = NULL;
    }

    return 0;
    }可是一旦这个线程开始执行,ACCEPT函数马上就返回错误这就让人非常费解了。
      

  19.   

    WSAEWOULDBLOCK是因为你用的是阻塞调用,等WM_SOCKET消息来吧,另外WM_SOCKET定以了吗?
    m_hWnd正确吗?
      

  20.   

    Swallowdeng_cq(JustTalk)老兄,我就是等着WM_SOCKET消息来的啊, 当然有定义WM_SOCKET消息啦,不然,编译都通过不了,那里还能轮得到运行时报错啊?m_hWnd我用的就是Dialog的m_hWnd数据成员啊,这个有问题吗?
      

  21.   

    自己用postmessage试一下就知道了嘛
      

  22.   

    连接不上是正常的。
    因为你没有把端口转换成网络字节顺序。saddr.sin_port = 10001;
    =============
    改为:saddr.sin_port = htons(10001);svraddr.sin_port = 10001;
    ==============================
    改为:svraddr.sin_port = htons(10001);
      

  23.   

    B2China(海陆空天电磁)老兄,不好意思,上次经一位大虾指点,我已经加上了htons的,忘了说出来。但问题依然还是存在的。。
      

  24.   


    你有没有把这个WM_SOCKET消息影射到接收函数(recieve)什么的呀?
    ON_MESSAGE(WM_SOCKET,OnReceive)
      

  25.   

    wenjhua(猫痕)(不要轻易说出I LOVE U) 老兄,看了我的源码,若我没有把这个WM_SOCKET消息影射到接收函数,如何能执行到调用accept函数的那个地方去?
      

  26.   

    你用阻塞模式时Accept返回的是什么错误?
      

  27.   

    返回的错误依然是WSAEWOULDBLOCK(10035)
      

  28.   

    你确认在客户端和服务端都加上了htons()?
    你把服务端程序移到本机上来调试吧!
      

  29.   

    异步情况下,connect是肯定会出错的,不过没有影响。
    客户端选择消息要加一条FD_CONNECT:
    WSAAsyncSelect(m_sock, m_hWnd, WM_SOCKET,FD_READ | FD_WRITE|FD_CONNECT);
    在响应FD_CONNECT消息时,调用select判断是否已经连接:
    fd_set curset;
    struct timeval waittime;
    waittime.tv_sec=0;
    waittime.tv_usec=0;
    FD_ZERO(&curset);
    FD_SET(this->clientsocket,&curset);
    sprintf(tmpchar,"已经连接上了,当前SOCKET 是%d",(int)CurSock);
    //curset.
    int ret=select(NULL,NULL,&curset,NULL,&waittime);
    if(ret==0)
    {
    //sprintf(tmpchar,"已经连接上了,当前SOCKET 是%d",(int)CurSock);
    this->SetDlgItemText(IDC_STATICSTATE,"连接失败!");
    this->connected=false;
    m_connect.EnableWindow();
    return;
    }
    else
    {
    if(ret==SOCKET_ERROR)
    {
    this->Showerror();
    this->SetDlgItemText(IDC_STATICSTATE,"连接失败!");
    m_connect.EnableWindow();
    return;
    }
    }
    还有:
    accept()失败后服务端会不停地收到FD_ACCEPT直到接受连接!!
    所以如果还不行的话,将服务端的WSAAsyncSelect放到bind后面
      

  30.   

    to microsy(光明三摩地) :
    客户端和服务器端都有加htons的,我一直都是在本地调试的服务端与客户端。to tgame(从此醉):
    我把您写的这段代码加到客户端的FD_CONNECT消息处理过程中了,connect函数仍然立即返回错误,跟踪进这段代码中,发现没有出现什么异常,顺利执行完毕。select函数返回1。但是服务端程序死了,也没有弹出“Accept fail”提示,不知还有什么没发现的问题,请赐教!
      

  31.   

    服务器不断的收到FD_ACCEPT消息。就象进入了死循环一样。我已经把将服务端的WSAAsyncSelect放到bind后面了。
      

  32.   

    服务端accept函数返回WSAEFAULT(10014)错误号。
      

  33.   

    噢,对了,如果你使用了WSAAsyncSelect,会导致socket进入非阻塞模式的,你必须再用ioctlsocket 再将其设置为阻塞模式!
      

  34.   

    WSAEFAULT 
    (10014) 
    Bad address. 
    The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument which is a struct sockaddr is smaller than sizeof(struct sockaddr). 
      

  35.   

    10014错误表示:参数错误
    sockaddr_in clientaddr;
    int addr_len=sizeof(sockaddr_in);
    accept(this->ServerSocket,(struct sockaddr FAR *)&(clientaddr),&addr_len);
    试试看
      

  36.   

    不好意思,是我弄错了sizeof的参数,已经改过了,现在accept函数返回正确了,可是到后面整个WM_SOCKET消息处理函数返回的时候,又报出了内存错误:
    (MSVCRTD.DLL) 0xC0000005:Access Violation.就一条语句: return 0;
      

  37.   

    to tgame(从此醉):
    要不您给我个邮箱,我把全部代码发给您看看,您帮着改改,再发回给我。[email protected](这是在下的邮箱)不知您意下如何?
      

  38.   

    谢谢tgame(从此醉) 大虾, 我已经把源码发给您了,请查收。
      

  39.   

    memset(saddr.sin_zero, 0, 8);
      

  40.   

    memset(saddr.sin_zero, 0, 8);
    去掉
      

  41.   

    多谢tgame(从此醉) 大虾,您发来的代码我收到了。试了一下,正确了!100分全数奉上! 请笑纳!