socket之UDP
什么是socket?
说道socket,就得说到客户端和服务端。通俗点讲,客户端是指就在我们旁边的,我们需要通过客户端去访问服务端,
做一些数据互动,起到通讯的作用。而服务端则是“远在天边”,但通过建立socket,我们也可以触碰到它。socket
的作用则是为客户端和服务端提供一个用于通讯的接口,通过这个接口,客户端可以和服务端进行通讯。
如何创建一个UDP通讯?
要建立一个UDP通讯,首先得有客户端和服务端这两个需要通讯的东东,不然谈何通讯。
①创建一个UDP客户端
我们要注意一点:使用连接的数据报套接字。因为我们在讲使用数据报,所以
我们需要了解它。如果我们的talker 程序使用了connect()函数来连接listener 的地址,那么
talker 程序就能够使用sent()和recv()来处理数据了。因为talker 程序在connect()函数中已
经知道了远程主机的地址和端口号.
②创建一个UDP服务端
什么是socket?
说道socket,就得说到客户端和服务端。通俗点讲,客户端是指就在我们旁边的,我们需要通过客户端去访问服务端,
做一些数据互动,起到通讯的作用。而服务端则是“远在天边”,但通过建立socket,我们也可以触碰到它。socket
的作用则是为客户端和服务端提供一个用于通讯的接口,通过这个接口,客户端可以和服务端进行通讯。
如何创建一个UDP通讯?
要建立一个UDP通讯,首先得有客户端和服务端这两个需要通讯的东东,不然谈何通讯。
①创建一个UDP客户端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
/* 要连接的端口 */
#define MYPORT 5000
int main(int argc, char *argv[])
{
int sockfd;
/* 连接者的地址信息 */
struct sockaddr_in their_addr;
struct hostent *he;
int numbytes;
if (argc != 3)
{
/* 检测是否有所须参数,如没有,则显示使用方法后退出 */
fprintf(stderr,“usage: talker hostname message\n”);
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL)
{
/* 取得主机的信息,如果失败则显示错误信息后退出 */
herror(“gethostbyname”);
exit(1);
}
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
/* 申请一个数据报套接字描述符,失败则退出 */
perror (“socket”);
exit(1);
}
/* 主机字节顺序 */
their_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型 */
their_addr.sin_port = htons(MYPORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
/* 将结构中未用的部分清零 */
bzero(&(their_addr.sin_zero), 8);
if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
/* 把信息发送到指定的主机指定端口,如出错则提示退出 */
perror(“recvfrom”);
exit(1);
}
printf(“sent %d bytes to %s\n”,numbytes,inet_ntoa(their_addr.sin_addr));
/* 关闭套接字描述符后退出 */
close(sockfd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/wait.h>
/* 要连接的端口 */
#define MYPORT 5000
int main(int argc, char *argv[])
{
int sockfd;
/* 连接者的地址信息 */
struct sockaddr_in their_addr;
struct hostent *he;
int numbytes;
if (argc != 3)
{
/* 检测是否有所须参数,如没有,则显示使用方法后退出 */
fprintf(stderr,“usage: talker hostname message\n”);
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL)
{
/* 取得主机的信息,如果失败则显示错误信息后退出 */
herror(“gethostbyname”);
exit(1);
}
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
/* 申请一个数据报套接字描述符,失败则退出 */
perror (“socket”);
exit(1);
}
/* 主机字节顺序 */
their_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型 */
their_addr.sin_port = htons(MYPORT);
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
/* 将结构中未用的部分清零 */
bzero(&(their_addr.sin_zero), 8);
if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
(struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)
{
/* 把信息发送到指定的主机指定端口,如出错则提示退出 */
perror(“recvfrom”);
exit(1);
}
printf(“sent %d bytes to %s\n”,numbytes,inet_ntoa(their_addr.sin_addr));
/* 关闭套接字描述符后退出 */
close(sockfd);
return 0;
}
我们要注意一点:使用连接的数据报套接字。因为我们在讲使用数据报,所以
我们需要了解它。如果我们的talker 程序使用了connect()函数来连接listener 的地址,那么
talker 程序就能够使用sent()和recv()来处理数据了。因为talker 程序在connect()函数中已
经知道了远程主机的地址和端口号.
②创建一个UDP服务端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
/* 要连接到的端口号 */
#define MYPORT 5000
/* 能够接收的最长数据 */
#define MAXBUFLEN 100
main()
{
int sockfd;
/* 本机的地址信息 */
struct sockaddr_in my_addr;
/* 连接这的地址信息 */
struct sockaddr_in their_addr;
int addr_len, numbytes;
char buf[MAXBUFLEN];
/* 取得一个套接字描述符 */
if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
/* 如果取得套接字描述符失败,则给出错误信息,退出 */
perror(“socket”);
exit(1);
}
/* 主机字节顺序 */
my_addr.sin_family = AF_INET;
/* 网络字节顺序,短整型 */
my_addr.sin_port = htons(MYPORT);
/* 自动设置为自己的IP */
my_addr.sin_addr.s_addr = INADDR_ANY;
/* 将结构的其余空间清零 */
bzero(&(my_addr.sin_zero), 8);
/* 绑定端口 */
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
/* 如果绑定端口出错,则显示错误信息然后退出 */
perror(“bind”);
exit(1);
}
addr_len = sizeof(struct sockaddr);
/* 接收数据 */
if ((numbytes=recvfrom(sockfd, buf, MAXBUFLEN, 0,
(struct sockaddr *)&their_addr, &addr_len)) == -1)
{
/* 如果recvfrom()调用出错,则显示错误信息后退出 */
perror(“recvfrom”);
exit(1);
}
/* 显示接收到的数据 */
printf(“got packet from %s\n”,inet_ntoa(their_addr.sin_addr));
printf(“packet is %d bytes long\n”,numbytes);
buf[numbytes] = ‘\0’;
printf(“packet contains \”%s\“\n”,buf);
/* 关闭套接字连接 */
close(sockfd);
}