0

クライアントとサーバーを使用して小さなアプリケーションを作成しています。クライアントが質問を送信し、サーバーが応答します。

私はなんとか最初の部分を行うことができました-サーバーはクライアントから質問を受け取り、いくつかの作業を行い、回答を送り返します。サーバーからの応答を待つようにクライアントに指示する方法がわかりません。

これは私のクライアントコードです:

char* ipAddress = (char*)malloc(15);
wcstombs(ipAddress, (TCHAR*)argv[1], 15);
DWORD port = wcstod(argv[2], _T('\0'));
DWORD numOfThreads = wcstod(argv[3], _T('\0;'));
DWORD method = wcstod(argv[4], _T('\0;'));

//initialize windows sockets service
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
assert(iResult==NO_ERROR);

//prepare server address
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ipAddress);
server_addr.sin_port = htons(port);

//create socket
SOCKET hClientSocket= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
assert(hClientSocket!=INVALID_SOCKET);

//connect to server
int nRes=connect(hClientSocket, (SOCKADDR*)&server_addr, sizeof(server_addr));
assert(nRes!=SOCKET_ERROR);

char* buf = "GET /count.htm HTTP/1.1\r\nHost: 127.0.0.1:666\r\nAccept: text/html,application/xhtml+xml\r\nAccept-Language: en-us\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/5.0\r\n\r\n";

int nBytesToSend= strlen(buf);
int iPos=0;

while(nBytesToSend)
{
    int nSent=send(hClientSocket,buf,nBytesToSend,0);
    assert(nSent!=SOCKET_ERROR);

    nBytesToSend-=nSent;
    iPos+=nSent;
}

closesocket(hClientSocket);

int nLen = sizeof(server_addr);
SOCKET hRecvSocket=accept(hClientSocket,(SOCKADDR*)&server_addr, &nLen);
assert(hRecvSocket!=INVALID_SOCKET);

//prepare buffer for incoming data
char serverBuff[256];
int nLeft=sizeof(serverBuff);
iPos=0;

do //loop till there are no more data
{
    int nNumBytes=recv(hRecvSocket,serverBuff+iPos,nLeft,0);

    //check if cleint closed connection
    if(!nNumBytes)
        break;

    assert(nNumBytes!=SOCKET_ERROR);

    //update free space and pointer to next byte
    nLeft-=nNumBytes;
    iPos+=nNumBytes;

}while(1);

SOCKET hRecvSocket=accept(hClientSocket,(SOCKADDR*)&server_addr, &nLen);行が失敗した後のアサーション。

4

1 に答える 1

1

「送信」ループの後の closesocket と accept 呼び出し - これらの呼び出しを削除します。accept は、着信接続をリッスンするサーバー用であり、既に接続されているクライアント用ではありません。

send() ループが完了したら、recv() ループに直接進みます。それはあなたの当面の問題を解決するはずです:

また、あなたの送信ループは、あなたが意図したと思うように、バッファ上の iPos を参照することを忘れています。これはあなたが望んでいたものです:

int nSent=send(hClientSocket,buf+iPos,nBytesToSend,0);

ネットワーク プログラミングでは、制御できないネットワーク状態が原因でソケットが失敗します。そのため、ネットワーク呼び出しでの「アサート」が常に適切であるとは限りません。失敗を予想して、それに対処する準備をする方がよいでしょう。通常、ソケットとアクティブな接続を閉じることが、ほとんどのエラーを処理する方法です。

于 2012-06-23T16:57:27.370 に答える