소켓 프로그래밍 스물여섯 : UDP 기반 서버 및 클라이언트

이전 글, 우리는 여러 TCP, UDP에 대한 예, 한 전술을 이해할 수로, 그것을 달성하기 어려운 일이 아니다을 제시한다.

UDP 서버와 클라이언트가 연결되지 않았습니다

UDP는 TCP와 달리, 접속 된 상태에서 데이터를 교환하지 않고 또한 연결 프로세스를 통하지 않고 서버 및 클라이언트를 UDP 기반. 즉, 호출들을 ()와 () 함수를 허용하지 않습니다. UDP 소켓은 프로세스와 데이터 교환 프로세스를 만들 수 있습니다.

UDP 서버와 클라이언트는 소켓입니다

TCP는 소켓이 하나 개의 관계에 대한 것입니다. 10 클라이언트 서비스를 제기하려면, 다음뿐만 아니라 소켓을 모니터링에 대한 책임뿐만 아니라, 소켓 (10)을 작성해야합니다. 그러나 UDP에, 서버 또는 클라이언트는 소켓을해야하는지 여부. UDP 시간의 원리를 설명하는 패키지를 우편의 예를 인용하기 전에 오랫동안 택배 회사가있는 한, 당신은 모든 주소 그것에 소포를 보낼 수있는, UDP 소켓에 비유 할 수있는 패키지 배달 회사를 메일 링을 담당합니다. 마찬가지로, 단지 UDP 소켓은 모든 호스트로 데이터를 전송할 수 있습니다.

수신 및 전송 기능 UDP를 기반으로

당신이 TCP 소켓을 만든 후에는 데이터를 전송할 때 TCP 소켓은 다른 소켓 연결에 남아 있기 때문에, 필요, 주소 정보를 추가 없습니다. 즉, TCP 소켓은 대상의 주소 정보를 알고있다. 하지만 UDP 소켓 연결 상태를 유지, 각각의 데이터 전송은 이전 메일 패키지에받는 사람의 주소를 입력하는 것과 동일 목적지 주소 정보를 추가해야되지 않습니다.

있는 sendto () 함수를 사용하여 데이터를 전송 :


ssize_t sendto(int sock, void *buf, size_t nbytes, int flags, struct sockaddr *to, socklen_t addrlen); //Linux
int sendto(SOCKET sock, const char *buf, int nbytes, int flags, const struct sockadr *to, int addrlen); //Windows

유사 () 함수에서 리눅스와 윈도우 sendto를, 다음은 자세한 매개 변수 설명입니다 :

  • 양말 : 소켓을 UDP 데이터의 전송을 위해;
  • BUF : 버퍼 어드레스가 송신 데이터에 저장하는 단계;
  • nbytes (바이트 단위)의 송신 데이터의 길이와;
  • 플래그 : 더 0이있는 경우 선택적 매개 변수는 전송 될 수 없다;
  • 로 : 주소 정보 SOCKADDR 구조 변수의 목표 어드레스에 저장;
  • addrlen : 가변 구조를 어드레스 값으로 전달 된 파라미터 길이.


UDP 전송 기능 sendto를 () 함수를 쓰기 및 TCP를 전송 () / 전송 ()는 가장 큰 차이는 그에게 목적지 주소 정보를 전달하는 그, sendto를 () 함수가 필요입니다.

에 recvfrom () 함수를 사용하여 수신 된 데이터 :


ssize_t recvfrom(int sock, void *buf, size_t nbytes, int flags, struct sockadr *from, socklen_t *addrlen); //Linux
int recvfrom(SOCKET sock, char *buf, int nbytes, int flags, const struct sockaddr *from, int *addrlen); //Windows

하는 UDP 데이터의 마지막에 한정 송신하기 때문에,에 recvfrom () 함수는 수신 측, 다음의 두 파라미터에 전송되는 정보의 형태로 정의된다 :

  • 양말 : UDP 데이터를 수신하기위한 소켓;
  • BUF : 어드레스 버퍼는 수신 데이터를 저장;
  • nbytes, 수신 바이트 수 (버퍼 (BUF)의 크기를 초과하지 않음)의 최대 수;
  • 플래그 : 더 0이있는 경우 선택적 매개 변수는 전송 될 수 없다;
  • 에서 : 송신 측의 어드레스 정보, 변수의 어드레스의 구조가 SOCKADDR;
  • addrlen : 저장된 가변 길이의 구조 매개 변수의 어드레스 값.

UDP를 에코 서버 / 클라이언트를 기반으로

이전에 실현 에코 클라이언트 내용의 다음과 같은 조합. 그것은 TCP에서 UDP의 달라, 주목해야한다, 어떠한 연결 요청 및 수용 과정이 없으며, 따라서 서버 측라는 서비스를 제공 간단하기 때문에, 어떤 의미에서, 서버와 클라이언트 사이에 명확한 구별 할 수 없다, 나는 그 독자가 오해하지 않습니다 바랍니다.

다음 코드는 윈도우, 리눅스 및 이와 유사한에서 주어진 그들을 반복하지.

서버 측 server.cpp :


#include <stdio.h>
#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib") //加载 ws2_32.dll

#define BUF_SIZE 100

int main(){
WSADATA wsaData;
WSAStartup( MAKEWORD(2, 2), &wsaData);

//创建套接字
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);

//绑定套接字
sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr)); //每个字节都用0填充
servAddr.sin_family = PF_INET; //使用IPv4地址
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); //自动获取IP地址
servAddr.sin_port = htons(1234); //端口
bind(sock, (SOCKADDR*)&servAddr, sizeof(SOCKADDR));

//接收客户端请求
SOCKADDR clntAddr; //客户端地址信息
int nSize = sizeof(SOCKADDR);
char buffer[BUF_SIZE]; //缓冲区
while(1){
int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &clntAddr, &nSize);
sendto(sock, buffer, strLen, 0, &clntAddr, nSize);
}

closesocket(sock);
WSACleanup();
return 0;
}

정의 :
코드 1) 라인, 소켓 (12), 소켓 () SOCK_DGRAM 두번째 파라미터를 생성하는 UDP 프로토콜의 사용을 나타낸다.

2) 사용 된 코드 라인 (18) htonl(INADDR_ANY)에 자동으로 IP 주소를 얻었다.

사용 상수의 INADDR_ANY 자동으로 IP 주소가 분명 장점이 얻을 소프트웨어가 IP 주소가 변경되어 다른 서버 나 서버에 설치되어있는 경우 소프트웨어를 시작할 때, 소스 코드의 변경을 재 컴파일 할 더 이상 필요가 수동으로 입력 할 필요가 없습니다 없다는 것입니다. IP 주소 (예를 들어, 라우터)를 복수의 컴퓨터에 할당되는 경우 또한, 한 포트 번호가 일치 한, 다른 IP 주소로부터 데이터를 수신 할 수있다. 따라서, 사용의 우선 순위를 서버 INADDR_ANY 상기 서버 펑션의 부분을 제외하고 클라이언트가이를 사용할 수 없다.

클라이언트 client.cpp :


#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll

#define BUF_SIZE 100

int main(){
//初始化DLL
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

//创建套接字
SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);

//服务器地址信息
sockaddr_in servAddr;
memset(&servAddr, 0, sizeof(servAddr)); //每个字节都用0填充
servAddr.sin_family = PF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons(1234);

//不断获取用户输入并发送给服务器,然后接受服务器数据
sockaddr fromAddr;
int addrLen = sizeof(fromAddr);
while(1){
char buffer[BUF_SIZE] = {0};
printf("Input a string: ");
gets(buffer);
sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
int strLen = recvfrom(sock, buffer, BUF_SIZE, 0, &fromAddr, &addrLen);
buffer[strLen] = 0;
printf("Message form server: %s\n", buffer);
}

closesocket(sock);
WSACleanup();
return 0;
}

서버를 실행하고 클라이언트를 실행, 클라이언트 출력은 다음과 같습니다

String로의 INPUT :  C 언어 중국어 네트워크
메시지 양식 서버 : C 언어 중국어 네트워크
의 INPUT String로 2012 년에 설립 된 c.biancheng.net
메시지 서버 형태 : 2,012 c.biancheng.net 년에 설립 된
의 INPUT 문자열입니다 :


UDP는 연결이 필요하지 않기 때문에 코드에서 볼 수 있듯이, 사용되지 않음 server.cpp 듣고 () 함수는, 또한, client.cpp 연결 () 함수를 사용하지 않습니다.

게시 33 개 원래 기사 · 원 찬양 30 ·은 20000 +를 볼

추천

출처blog.csdn.net/baidu_15547923/article/details/90230528