首页 新闻 会员 周边 捐助

socket不断关闭打开连接不 可以,怎么办?

0
悬赏园豆:120 [已解决问题] 解决于 2014-06-27 21:17

Server:

#include <iostream>
#include <WinSock2.h>

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

#define NUM_SEND_CHAR 30

int main()
{
    WSAData wsaData;

    WSAStartup(MAKEWORD(2,2),&wsaData);
    SOCKET sktServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    sockaddr_in addrServer;
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.s_addr=inet_addr("127.0.0.1");
    addrServer.sin_port=htons(4000);
    bind(sktServer,(sockaddr*)&addrServer,sizeof(addrServer));
    listen(sktServer,5);

    std::cout<<"Recv Data"<<std::endl;

    int iErrorCode;
    while(true)
    {
        sockaddr_in addrAccept;
        int len=sizeof(addrAccept);
        SOCKET sktAccept=accept(sktServer,(sockaddr*)&addrAccept,&len);
        if(INVALID_SOCKET==sktAccept)
            continue;

        char* pRecvData=new char[NUM_SEND_CHAR];
        memset(pRecvData,0,NUM_SEND_CHAR);
        iErrorCode=recv(sktAccept,pRecvData,NUM_SEND_CHAR,0);
        /*
        if(SOCKET_ERROR==iErrorCode)
        {
            if( WSAGetLastError()==WSAEWOULDBLOCK )
                continue;
            std::cout<<"Recv failed."<<std::endl;
            closesocket(sktServer);
            WSACleanup();
            return -1;
        }
        */
        std::cout<<"Recv Data : "<<pRecvData<<std::endl;
        delete [] pRecvData;
        sktAccept=INVALID_SOCKET;
    }

    std::cout<<"Over"<<std::endl;
    getchar();
    return 0;
}

Client:

#include <iostream>
#include <WinSock2.h>

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

#define NUM_SEND_CHAR 30

DWORD __stdcall Perform(void* pParam);


int identity=1;

int main()
{
    WSAData wsaData;
    int iErrorCode;
    
    WSAStartup(MAKEWORD(2,2),&wsaData);
    SOCKET sktClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    sockaddr_in addrServer;
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.s_addr=inet_addr("127.0.0.1");
    addrServer.sin_port=htons(4000);
    iErrorCode=connect(sktClient,(sockaddr*)&addrServer,sizeof(addrServer));
    if(SOCKET_ERROR==iErrorCode)
    {
        std::cout<<"Connecting failed."<<std::endl;
        closesocket(sktClient);
        WSACleanup();
        return -1;
    }

    while(true)
    {
        char* pSendChar=new char[NUM_SEND_CHAR];
        memset(pSendChar,0,NUM_SEND_CHAR);
        memset(pSendChar,(char)(((int)'0')+identity++),NUM_SEND_CHAR-1);
        iErrorCode=send(sktClient,pSendChar,NUM_SEND_CHAR,0);
        /*
        if(SOCKET_ERROR==iErrorCode)
        {
            std::cout<<"Sending failed."<<std::endl;
            closesocket(sktClient);
            WSACleanup();
            return -1;
        }
        */
        delete [] pSendChar;
        std::cout<<"Sending the data..."<<std::endl;
    }

    closesocket(sktClient);
    WSACleanup();

    std::cout<<"Over"<<std::endl;
    getchar();
    return 0;
}

显示结果:

 

期望结果 是显示:

1111111111111

2222222222222

3333333333333

。。。

疑惑:为什么只接收了 一次就不能循环下去?

 

============================

后来修改代码如下:

server:

#include <iostream>
#include <WinSock2.h>
#include <exception>
#pragma comment(lib,"ws2_32.lib")

#define NUM_SEND_CHAR 30

int main()
{
    WSAData wsaData;

    WSAStartup(MAKEWORD(2,2),&wsaData);
    SOCKET sktServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    sockaddr_in addrServer;
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.s_addr=inet_addr("127.0.0.1");
    addrServer.sin_port=htons(4000);
    bind(sktServer,(sockaddr*)&addrServer,sizeof(addrServer));
    listen(sktServer,5);

    std::cout<<"Recv Data"<<std::endl;

    int iErrorCode;
    while(true)
    {
        try{
        
            sockaddr_in addrAccept;
            int len=sizeof(addrAccept);
            SOCKET sktAccept=accept(sktServer,(sockaddr*)&addrAccept,&len);
            if(INVALID_SOCKET==sktAccept)
                continue;

            char* pRecvData=new char[NUM_SEND_CHAR];
            memset(pRecvData,0,NUM_SEND_CHAR);
            iErrorCode=recv(sktAccept,pRecvData,NUM_SEND_CHAR,0);
            /*
            if(SOCKET_ERROR==iErrorCode)
            {
                if( WSAGetLastError()==WSAEWOULDBLOCK )
                    continue;
                std::cout<<"Recv failed."<<std::endl;
                closesocket(sktServer);
                WSACleanup();
                return -1;
            }
            */
            std::cout<<"Recv Data : "<<pRecvData<<std::endl;
            delete [] pRecvData;
            /*
            closesocket(sktAccept);
            Sleep(4000);
            */
            shutdown(sktAccept,2);
        }
        catch (...)
        {
            std::cout<<"Exception : "<<std::endl;
        }
        
    }

    std::cout<<"Over"<<std::endl;
    getchar();
    return 0;
}

Client:

#include <iostream>
#include <WinSock2.h>

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

#define NUM_SEND_CHAR 30

DWORD __stdcall Perform(void* pParam);


int identity=1;

int main()
{
    WSAData wsaData;
    int iErrorCode;
    
    WSAStartup(MAKEWORD(2,2),&wsaData);
    
    sockaddr_in addrServer;
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.s_addr=inet_addr("127.0.0.1");
    addrServer.sin_port=htons(4000);

    while(true)
    {
    //移动一下位置 SOCKET sktClient
=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); iErrorCode=connect(sktClient,(sockaddr*)&addrServer,sizeof(addrServer)); if(SOCKET_ERROR==iErrorCode) { continue; } char* pSendChar=new char[NUM_SEND_CHAR]; memset(pSendChar,0,NUM_SEND_CHAR); memset(pSendChar,(char)(((int)'0')+identity++),NUM_SEND_CHAR-1); iErrorCode=send(sktClient,pSendChar,NUM_SEND_CHAR,0); /* if(SOCKET_ERROR==iErrorCode) { std::cout<<"Sending failed."<<std::endl; closesocket(sktClient); WSACleanup(); return -1; } */ delete [] pSendChar; std::cout<<"Sending the data..."<<std::endl; shutdown(sktClient,2); } WSACleanup(); std::cout<<"Over"<<std::endl; getchar(); return 0; }

这样可以见到预期的效果,当然电脑会报警的,呵呵!

guanlongcun的主页 guanlongcun | 初学一级 | 园豆:16
提问于:2014-05-17 18:10
< >
分享
最佳答案
0

你server端accept一个socket后只recv了一次,打印输出后,然后就没有理它,继续accept下一个socket。 也就是说,server端对同一个socket只会调用一次接收,自然只会有一次输出。

要想接收多个输出,应该在对每个个socket开一个循环,在循环中调用recv语句才对呀。

收获园豆:120
天方 | 大侠五级 |园豆:5432 | 2014-05-17 21:03

那样是可以的,其实这个代码是用来同时开多个Client的,这样就有两个问题需要解决:

1,client怎样知道自己的socket缓冲区中上次发送的数据已经清空了,可以进行下一次发送?

2,因为client发送数据时,server的 recv是阻塞的。所以server recv时候怎么确保client没有在发送数据?

求助中。。。

guanlongcun | 园豆:16 (初学一级) | 2014-05-18 11:46
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册