TCP의 스티커 문제 및 데이터의 무경계성

4227 단어
서비스 포트:
#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")  //   ws2_32.dll
 
#define BUF_SIZE 100
 
int main(int argc, char *argv[]){
    //    DLL
    WSADATA wsaData;
    WSAStartup( MAKEWORD(2, 2), &wsaData);
  
    //     
    SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(servSock == INVALID_SOCKET)
    {
        printf("Failed socket().
");         WSACleanup();         return 0;     }        //     struct sockaddr_in sockAddr;     memset(&sockAddr, 0, sizeof(sockAddr));  // 0     sockAddr.sin_family = PF_INET;  // IPv4     sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  // IP     sockAddr.sin_port = htons(1234);  //     if(bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)     {         printf("Failed bind().
");         WSACleanup();         return 0;     }        //     listen(servSock, 20);        //     int nSize = sizeof(SOCKADDR);     char buffer[BUF_SIZE];//       SOCKADDR clntAddr;     SOCKET clntSock;            for(;;)     {         clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);         Sleep(10000);// , 10                    int strLen = recv(clntSock, buffer, BUF_SIZE, 0);//                    if(clntSock == INVALID_SOCKET)         {             printf("Failed accept().
");             continue;         }         //           send(clntSock, buffer, strLen, 0);                   memset(buffer, 0, BUF_SIZE);//                     //         closesocket(clntSock);     }        //     closesocket(servSock);        //  DLL      WSACleanup();        return 0; }

클라이언트:
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")

#define BUF_SIZE 100
 
int main(int argc, char *agrv[])
{
    //   DLL
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
      
    for(;;)
    {
     
        //     
        SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sock == INVALID_SOCKET)
        {
            printf("Failed socket().
");             WSACleanup();             return 0;         }                //         struct sockaddr_in sockAddr;         memset(&sockAddr, 0, sizeof(sockAddr)); // 0         sockAddr.sin_family = PF_INET;         sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");         sockAddr.sin_port = htons(1234);         if(connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)) == -1)         {             printf("Failed connect().
");             WSACleanup();             return 0;         }                //           char bufSend[BUF_SIZE] = {0};         printf("
Input a string: ");         gets(bufSend);         int i;         for(i=0; i<3; i++)         {             send(sock, bufSend, strlen(bufSend), 0);         }                  //           char bufRecv[BUF_SIZE] = {0};         int nRecv = recv(sock, bufRecv, BUF_SIZE, 0);         if(nRecv > 0)         {             bufRecv[nRecv] = '\0';             //             printf("Message from server: %s
", bufRecv);         }         memset(bufSend, 0, BUF_SIZE);//         memset(bufRecv, 0, BUF_SIZE);//                     //         closesocket(sock);     }                         // DLL     WSACleanup();           return 0;  }

서버를 먼저 실행하고client를 실행하며 10초 안에 문자열 "abc"를 입력하고 몇 초를 기다리면 서버가 데이터를 되돌려줍니다.실행 결과는 다음과 같습니다. Input a string: abcMessage form server: abcabcabc 이 프로그램의 관건은 서버입니다.cpp 31행의 코드 Sleep(10000); 는 프로그램의 실행을 10초 동안 중단시킨다.이 시간 동안client는 세 번 연속 문자열 "abc"를 보냈습니다. 서버가 막혀서 데이터는 버퍼에 쌓일 수 밖에 없습니다. 10초 후에 서버가 실행되기 시작하여 버퍼에서 모든 쌓인 데이터를 한꺼번에 읽고 클라이언트에게 되돌려줍니다.그리고 더 설명해야 할 것은client입니다.cpp 34행 코드.client는recv () 함수에 실행됩니다. 입력 버퍼에 데이터가 없기 때문에, 10초 후에 서버가 데이터를 전송해야 실행됩니다.사용자가 보는 직관적인 효과는 서버가 되돌아오는 결과를 출력하기 위해 클라이언트가 잠시 멈추는 것이다.client의send()는 세 개의 패키지를 보냈지만 서버의recv()는 한 개의 패키지만 받았습니다. 이것은 데이터의 패키지 문제를 잘 설명합니다.

좋은 웹페이지 즐겨찾기