Tips :
The features of UDP
1、connectionless
2、message based on data transmission service
3、unreliable transmission
4、for the most times , UDP is more efficient
Some points of UDP to be mentioned:
1、the message of UDP may lose , repeat
2、sometimes it may be disordered
3、also UDP lacks some protocol to control data
4、there may be some packet truncation happened to UDP
5、when recvfrom function return 0 , it doesn't mean the connection is closed , because UDP is a connectionless protocol.
6、the asynchronous error of ICMP
7、UDP connect
8、the certain of UDP outgoing interface.
Client :
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m) ;\
exit(EXIT_FAILURE) ;\
}while(0)
void
echo_cli ( int sock )
{
struct sockaddr_in servaddr ;
memset ( &servaddr , 0 , sizeof(servaddr) ) ;
servaddr.sin_family = AF_INET ;
servaddr.sin_port = htons(5188) ;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1") ;
//connect ( sock , (struct sockaddr*) &servaddr , sizeof(servaddr) ) ;(3)
int ret ;
char sendbuf[1024] ={0} ;
char recvbuf[1024] ={0} ;
while( ( fgets(sendbuf , sizeof(sendbuf) , stdin) ) != NULL )
{
sendto(sock, sendbuf, strlen(sendbuf) , 0 , (struct sockaddr*) &servaddr , sizeof(servaddr) ) ;
// sendto ( sock , sendbuf , strlen(sendbuf) , 0 , NULL , 0 ) ;(1)
// send ( sock , sendbuf , strlen(sendbuf) , 0 ) ;(2)
//(1),(2) can be both used when we add connect function(3).
ret = recvfrom ( sock , recvbuf , sizeof(recvbuf) , 0 , NULL , NULL ) ;
if ( -1 == ret )
{
if ( EINTR == errno )
{
continue ;
}
ERR_EXIT("recvfrom") ;
}
fputs ( recvbuf , stdout ) ;
memset ( recvbuf , 0 , sizeof(recvbuf) ) ;
memset ( sendbuf , 0 , sizeof(sendbuf) ) ;
}
close(sock) ;
}
int
main(void)
{
int sock ;
if ( ( sock = socket ( PF_INET , SOCK_DGRAM , 0 ) ) < 0 )
{
ERR_EXIT("sock") ;
}
echo_cli(sock) ;
return 0 ;
}
Server:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m) ;\
exit(EXIT_FAILURE) ;\
}while(0)
void echo_serv ( int sock )
{
char recvbuf[1024] = {0} ;
struct sockaddr_in peeraddr ;
socklen_t peerlen = sizeof(peeraddr) ;
while(1)
{
memset ( recvbuf , 0 , sizeof(recvbuf)) ;
int n = recvfrom ( sock , recvbuf , sizeof(recvbuf) , 0 , (struct sockaddr*) &peeraddr ,& peerlen ) ;
if ( -1 == n )
{
if ( EINTR == errno )
{
continue ;
}
ERR_EXIT("recvfrom") ;
}
else if ( n > 0 )
{
fputs ( recvbuf , stdout ) ;
sendto ( sock , recvbuf , n , 0 , ( struct sockaddr*) &peeraddr , peerlen) ;
}
}
close(sock) ;
}
int
main(void)
{
int sock ;
if ( ( sock = socket ( PF_INET , SOCK_DGRAM , 0 ) ) < 0 )
{
ERR_EXIT("sock") ;
}
struct sockaddr_in servaddr ;
memset ( &servaddr , 0 , sizeof(servaddr) ) ;
servaddr.sin_family = AF_INET ;
servaddr.sin_port = htons(5188) ;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY) ;
if ( bind(sock,(struct sockaddr*) &servaddr , sizeof(servaddr) ) < 0 )
{
ERR_EXIT("bind") ;
}
echo_serv ( sock ) ;
return 0 ;
}