UDP是无连接不可靠的数据报协议,非常不同于TCP提供的面向连接的可靠字节流。
典型的UDP客户/服务器程序,客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报。类似地,服务器不接受来自客户端地连接,而是只管调用recvfrom函数。
1. 服务器程序demo
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#define MAXLINE 4096
void dg_echo(int sockfd, struct sockaddr * pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE] = {0};
for( ; ; ) {
len = clilen;
bzero(mesg, sizeof(mesg));
/* receive msg and send back */
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
printf("receive mesg %s, len = %d\n",mesg, n);
sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
/* socket init */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
/* server init & bind */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8888); /* 16-bit TCP or UDP port number */
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
dg_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
}
2. 客户端程序demo
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
void dg_cli(int sockfd, const struct sockaddr *pservaddr, socklen_t servlen)
{
int n;
char sendline[100], recvline[100 + 1];
while(fgets(sendline, 100, stdin) != NULL) {
sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);
n = recvfrom(sockfd, recvline, 100, 0, NULL, NULL);
recvline[n] = 0;
fputs(recvline, stdout);
}
}
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc != 2) {
printf("usage: udpcli <IPaddress>\n");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
dg_cli(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
exit(0);
}