시스템 프로그래밍의 UDP 네트워크 프로그래밍(순환 서버)

21288 단어

1. 서버 기본 작업


1. socket () 함수로 socket을 만들고, 반환값은 socket의 식별자 sockfd입니다. 이 식별자는 뒤에서 사용됩니다.
2. 구조체 sockaddr_로서버 정보 저장 (프로토콜, 포트, IP) 연합체 구성원:structsockaddr_in sever_addr {sever_addr.sin_family//프로토콜 sever_addr.sinuport//포트, 일반적으로 1024 sever_addr.sin_addr.s_addr//ip보다 큽니다}
3.bind() 함수로 정보 귀속 주의: 두 번째 매개 변수는 (structsockaddr*) 형식으로 변환해야 합니다
4. sockaddr_로in 함수로 클라이언트 정보 저장
6. while 순환에서 recvfrom () 함수로 끊임없이 정보를 수신하고 인쇄
7.close 함수로 socket 닫기
서버 코드:
#include 
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 


int main()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);   //IPV4   
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    struct sockaddr_in server_addr;     // 
    memset(&server_addr, 0, sizeof(server_addr));   // 
    server_addr.sin_family = AF_INET;    // 
    server_addr.sin_port = 8000;        // 
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");     //ip 
    // 
    int ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }

    char buf[32] = {0};
    struct sockaddr_in client_addr;   // 
    int length = sizeof(client_addr);
    while(1)
    {
        ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&client_addr, &length);
        if(-1 == ret)
        {
            perror("recvfrom");
            exit(1);
        }
        printf(" %d  : %s
"
, client_addr.sin_port, buf); memset(buf, 0, sizeof(buf)); } return 0; }

클라이언트 기본 작업


1. socket () 함수로 socket을 만들고 값이 socket인 식별자 sockfd를 되돌려줍니다. 뒤에 식별자가 사용됩니다.
2. sockaddr_로in 구조체에서 서버 정보 저장
3. while 순환 안에서
4. sendto () 함수로 끊임없이 메시지 보내기
5. close 함수로 socket 끄기
클라이언트 코드:
#include 
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    char buf[32] = {0};
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = 8000;
    server_addr.sin_addr.s_addr =inet_addr("127.0.0.1");

    int length = sizeof(server_addr);
    while(1)
    {
        scanf("%s",buf);

        int ret = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, length);
        if(-1 == ret)
        {
            perror("sendto");
            exit(1);
        }

        if(!strcmp(buf, "bye"))
        {
            break;
        }

        memset(buf, 0, sizeof(buf));
    }

    close(sockfd);
    return 0;
}

상용 함수


recvfrom () 함수


함수 원형: 함수 원형:ssize_t recvfrom(int sockfd,void *buf,int len,unsigned int flags, struct sockaddr *from,socket_t *fromlen); ssize_t는 int에 해당, socket_t는 int에 해당한다. 여기서 이 이름을 사용하는 것은 코드의 자설명성을 높이기 위한 것이다.
기능: socket을 통해 데이터 수신
매개변수:
sockfd: 연결된 인터페이스의 설명자를 표시합니다.
buf: 수신 데이터 버퍼.
len: 버퍼 길이입니다.
flags: 조작 방식을 호출합니다.or 작업을 통해 연결할 수 있는 다음 로고 또는 여러 개의 조합체입니다. (기본값은 0)
from: 클라이언트 구조체 이름의 주소 (struct sockaddr *) 형식으로 변환해야 함)
fromlen: 클라이언트 구조체 길이의 주소
반환값: 성공하면 수신한 문자 수, 실패는 -1로 반환됩니다.

sendto () 함수


함수 원형:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
기능: 지정한 sockfd를 사용하여 지정한 바이트 수의 데이터를 지정한 종결점으로 보냅니다.
매개 변수:sockfd: 포트의 인터페이스 파일 설명자를 감청하고 있습니다. socket을 통해
buf: 전송 버퍼는 사용자가 정의한 그룹입니다. 이 그룹에는 전송할 데이터가 설치되어 있습니다.
len: 전송 버퍼 크기, 단위는 바이트입니다.
flags: 0을 채우면 됩니다.
dest_addr: 데이터를 수신하는 호스트 주소 정보의 구조체, 즉 이 매개 변수가 지정한 데이터를 어느 호스트로 보낼 프로세스를 가리킨다
addrlen: 다섯 번째 매개 변수가 가리키는 내용의 길이를 표시합니다
반환값: 전송된 데이터의 길이를 성공적으로 반환하고, 실패를 반환-1

socket () 함수


함수 원형: int socket(int sockfd, int type, int protocol);
기능: socket 설명자 (socket descriptor) 를 만드는 데 사용되며, 유일하게 socket을 표시합니다.이 socket 설명자는 파일 설명자와 마찬가지로 후속 작업은 모두 그것에 사용되며, 그것을 매개 변수로 삼아 그것을 통해 읽기와 쓰기를 한다.
매개 변수: 첫 번째 매개 변수: 프로토콜 필드, 프로토콜 패밀리 (family) 라고도 합니다.자주 사용하는 프로토콜족은 AF_INET、AF_INET6、AF_LOCAL(또는 AF_UNIX, Unix 도메인 소켓), AF_루트야, 잠깐만.프로토콜족은 socket의 주소 유형을 결정하고 통신에 대응하는 주소를 사용해야 한다. 예를 들어 AF_INET는 ipv4 주소(32비트)와 포트 번호(16비트)의 조합, AF_UNIX는 절대 경로 이름을 주소로 사용하기로 결정했습니다.
두 번째 인자: socket 형식을 지정합니다.자주 사용하는 socket 유형은 SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET 등등 (socket의 유형은 무엇입니까?).
세 번째 매개변수(기본값 0): 프로토콜을 지정합니다.일반적인 프로토콜은 IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC 등은 TCP 전송 프로토콜, UDP 전송 프로토콜, STCP 전송 프로토콜, TIPC 전송 프로토콜에 대응한다.
주의: 위의 type과 프로토콜이 임의로 조합할 수 있는 것은 아닙니다. 예를 들어 SOCK_STREAM은 IPROTO와 함께 하면 안 됩니다 _UDP 조합.프로토콜이 0이면 type 형식에 대응하는 기본 프로토콜을 자동으로 선택합니다.
반환값: 성공하면 socket의 표시부호 sockid를 반환하고, 실패하면 -1을 반환합니다.

bind() 함수


함수 원형: intbind(intsockfd,conststructsockaddr*addr,socklenutaddrlen);
기능: 한 주소족의 특정 주소를 socket에 부여합니다.우리가 socket을 호출해서 socket을 만들 때, 되돌아오는 socket 설명자는 프로토콜족 (address family, AF_XX) 공간에 존재하지만, 구체적인 주소는 없습니다.주소를 지정하려면bind () 함수를 호출해야 합니다. 그렇지 않으면connect (), listen () 를 호출할 때 시스템이 자동으로 랜덤으로 포트를 분배합니다.
매개 변수: 첫 번째 매개 변수: 즉 socket 설명자입니다. 이것은 socket () 함수를 통해 만들어진 것입니다. 유일한 표지는 socket입니다.bind () 함수는 이 설명자에 이름을 연결하는 것입니다.
두 번째 매개 변수: sockfd에 연결할 프로토콜 주소를 가리키는 conststructsockaddr * 바늘입니다.이 주소 구조는 주소가 socket을 만들 때의 주소 프로토콜족에 따라 다르다. 예를 들어 ipv4에 대응하는 것은:structsockaddr_in server_addr{ server_addr.sin_family = AF_INET; server_addr.sin_port = 800; server_addr.sin_addr.s_addr = inet_addr(“127.0.0.1”); }; struct sockaddr 형식으로 강하게 전환해야 합니다.
세 번째 매개 변수: 대응하는 것은 주소의 길이입니다.
반환값: 0 반환 성공, 실패 반환-1;
보통 서버는 시작할 때 모두가 알고 있는 주소(예를 들어 IP 주소+포트 번호)를 연결시켜 서비스를 제공하는데 고객은 이를 통해 서버를 연결할 수 있다.클라이언트는 지정할 필요가 없고 시스템이 자동으로 포트 번호와 자신의 IP 주소 조합을 분배한다.이것이 바로 일반적인 서버 측이listen 전에bind () 를 호출하고 클라이언트는 호출하지 않으며,connect () 시 시스템에서 무작위로 하나를 생성하는 이유입니다.

close () 함수


마치 열린 파일을 조작하고 fclose를 호출하여 열린 파일을 닫고, 읽기와 쓰기가 끝난 후에 마지막으로 파일을 닫는 것 같습니다.
함수 원형: int close(int fd);
매개 변수: 소켓 함수와accept 함수의 반환값;

좋은 웹페이지 즐겨찾기