socket programming twenty-six: UDP-based server and client

The previous article, we present several examples of TCP, UDP for, as long as able to understand the foregoing, it is not difficult to achieve.

UDP in the server and the client is not connected

Unlike the TCP UDP, without exchanging data in the connected state, the UDP-based server and client also without passing through the connection process. In other words, do not call listen () and accept () function. UDP sockets only to create the processes and data exchange process.

UDP server and client are just a socket

TCP, a socket is a one to one relationship. To file a 10 client service, then in addition is responsible for monitoring the socket, but also need to create a socket 10. But in the UDP, whether the server or the client only needs a socket. Before explaining the principle of UDP time cited the example of mailing a package, is responsible for mailing a package delivery company can be likened to UDP sockets, as long as there is a courier company, you can send a parcel to any address it. Similarly, only a UDP socket can transmit data to any host.

Receive and transmit functions based on UDP

Once you've created a TCP socket, no need to add address information when transmitting data, because TCP socket will remain with the other socket connection. In other words, TCP sockets know the target address information. But UDP socket will not stay connected, each data transmission must add the destination address information, which is equivalent to fill in the recipient address prior to mail packages.

Transmitting data using the sendto () function:


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

Linux and Windows sendto under similar () function, the following is the detailed parameter descriptions:

  • sock: socket for the transmission of UDP data;
  • buf: buffer address to be stored in the transmission data;
  • nbytes: with a length of the transmission data (in bytes);
  • flags: Optional parameters may be transmitted if there is no 0;
  • to: address information stored with the target address of sockaddr structure variables;
  • addrlen: length parameter passed to the address value to a variable structure.


UDP send function sendto () function write and send TCP () / send () is the biggest difference is that, sendto () function need to pass the destination address information to him.

Received data using the recvfrom () function:


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

Since the end of the UDP data transmitting indefinite, the recvfrom () function is defined in the form of information sent to the reception side, the following two parameters:

  • sock: a socket for receiving UDP data;
  • buf: save the received data buffer address;
  • nbytes: maximum number of bytes that can be received (not exceed the size of the buffer buf);
  • flags: Optional parameters may be transmitted if there is no 0;
  • from: the address information of the transmitting end there sockaddr structure of the variable address;
  • addrlen: variable address value of the variable length structure parameters from the saved.

Based on the UDP echo server / client

The following combination of realization echo client content before. It should be noted, UDP differs from TCP, there is no connection request and acceptance process, and therefore can not be a clear distinction between server and client, in a sense, simply because it provides a service called server-side, I hope that readers will not misunderstand.

The following code is given under Windows, Linux and similar, not repeat them.

Server-side 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;
}

Definitions:
1) line of code when creating the socket 12, the socket () SOCK_DGRAM second parameter, indicating the use of the UDP protocol.

2) code line 18 used htonl(INADDR_ANY)to automatically obtain an IP address.

Use constant INADDR_ANY automatically obtain an IP address has an obvious advantage is that when the software is installed to a different server or servers IP address is changed, no longer need to recompile the source code changes, do not have to be entered manually when you start the software. Further, if a computer in the plurality of IP addresses (e.g., a router) is assigned, as long as the port number is consistent, it may receive data from different IP addresses. Therefore, prioritize server using INADDR_ANY; and client except with the part of the server function, it would not be used.

Client 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;
}

Run the server, and then run the client, client output is:

A String the INPUT:  C language Chinese network
Message form server: C language Chinese network
the INPUT A String: c.biancheng.net Founded in 2012
the Message Server form: Founded in 2012 c.biancheng.net
the INPUT A String:


As can be seen from the code, not used server.cpp listen () function, is also not used client.cpp connect () function, since UDP does not require connection.

Published 33 original articles · won praise 30 · views 20000 +

Guess you like

Origin blog.csdn.net/baidu_15547923/article/details/90230528