"); //-->

实现一个基于UDP的应用
UDP的所调用的函数和用于TCP的函数非常类似。这主要因为套接口库在底层的TCP和UDP函数上加了一层抽象。
在使用TCP和使用UDP之间,函数调用的惟一实际区别在于socket函数调用的一个参数。这个参数为SOCK_STREAM时代表TCP,而SOCK_DGRAM代表UDP。
使用UDP发送数据
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port = 6789;
void main() {
int socket_descriptor;
int iter = 0;
char buf[80];
struct sockaddr_in address;
/* Initialize socket address structure for Internet Protocols*/
bzero(&address, sizeof(address)); /* empty data structure */
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(port);
/* Create a UDP socket*/
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
/* Loop 20 times (a nice round number) sending data.*/
for (iter = 0; iter <= 20; iter++)
{
sprintf(buf,"data packet with ID %d\n", iter);
sendto(socket_descriptor,
buf, sizeof(buf),
0, (struct sockaddr *)&address, sizeof(address));
}
/* Send a termination message*/
sprintf(buf, "stop\n");
sendto(socket_descriptor,
buf, sizeof(buf),
0, (struct sockaddr *)&address, sizeof(address));
close(socket_descriptor);
printf("Messages Sent, Terminating\n");
exit (0);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port = 6789;
void main() {
int sin_len;
char message[256];
int socket_descriptor;
struct sockaddr_in sin;
printf("Waiting for data from sender\n");
/* Initialize socket address structure for Internet Protocols*/
bzero(&sin, sizeof(sin)); /* empty data structure */
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);
sin_len = sizeof(sin);
/*
Create a UDP socket
and bind it to the port
*/
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin));
/*
Loop forever (or until a termination message is received)
Receive data through the socket and process it. The processing
in this program is really simple -- printing.
*/
while (1)
{
recvfrom(socket_descriptor, message, sizeof(message), 0,
(struct sockaddr *)&sin, &sin_len);
printf("Response from server: %s\n", message);
if (strncmp(message, "stop", 4) == 0)
{
printf("Sender has told me to end the connection\n");
break;
}
}
close(socket_descriptor);
exit (0);
}
--- sender.c 2000-09-22 20:51:26.000000000 +0800
+++ sender2.c 2000-09-22 20:51:26.000000000 +0800
@@ -5,45 +5,83 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <errno.h>
int port = 6789;
void main() {
int socket_descriptor;
int iter = 0;
+ ssize_t sendto_rc;
+ int close_rc;
char buf[80];
struct sockaddr_in address;
+ struct hostent *hostbyname;
/*
+ Translate a host name to IP address
+*/
+ hostbyname = gethostbyname("127.0.0.1");
+ if (hostbyname == NULL)
+ {
+ perror ("gethostbyname failed");
+ exit (errno);
+ }
+/*
Initialize socket address structure for Internet Protocols
+ The address comes from the datastructure returned by gethostbyname()
*/
bzero(&address, sizeof(address)); /* empty data structure */
address.sin_family = AF_INET;
- address.sin_addr.s_addr = inet_addr("127.0.0.1");
+ memcpy(&address.sin_addr.s_addr, hostbyname->h_addr, sizeof(address.sin_addr.s_addr));
address.sin_port = htons(port);
/*
Create a UDP socket
*/
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
+ if (socket_descriptor == -1)
+ {
+ perror ("socket call failed");
+ exit (errno);
+ }
/*
Loop 20 times (a nice round number) sending data.
*/
for (iter = 0; iter <= 20; iter++)
{
sprintf(buf,"data packet with ID %d\n", iter);
- sendto(socket_descriptor,
+ sendto_rc = sendto(socket_descriptor,
buf, sizeof(buf),
0, (struct sockaddr *)&address, sizeof(address));
+ if (sendto_rc == -1)
+ {
+ perror ("sendto call failed");
+ exit (errno);
+ }
}
/*
Send a termination message
*/
sprintf(buf, "stop\n");
- sendto(socket_descriptor,
+ sendto_rc = sendto(socket_descriptor,
buf, sizeof(buf),
0, (struct sockaddr *)&address, sizeof(address));
+ if (sendto_rc == -1)
+ {
+ perror ("sendto STOP call failed");
+ exit (errno);
+ }
+/*
+ Most people don't bother to check the return code
+ returned by the close function
+*/
+ close_rc = close(socket_descriptor);
+ if (close_rc == -1)
+ {
+ perror ("close call failed");
+ exit (errno);
+ }
- close(socket_descriptor);
printf("Messages Sent, Terminating\n");
exit (0);
}
--- receiver.c 2000-09-22 20:51:26.000000000 +0800
+++ receiver2.c 2000-09-22 20:51:26.000000000 +0800
@@ -5,6 +5,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+#include <errno.h>
int port = 6789;
@@ -13,6 +14,9 @@
char message[256];
int socket_descriptor;
struct sockaddr_in sin;
+ int bind_rc, close_rc;
+ ssize_t recv_rc;
+
printf("Waiting for data from sender\n");
/*
Initialize socket address structure for Internet Protocols
@@ -27,7 +31,18 @@
and bind it to the port
*/
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
- bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin));
+ if (socket_descriptor == -1)
+ {
+ perror ("socket call failed");
+ exit (errno);
+ }
+
+ bind_rc = bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin));
+ if (bind_rc == -1)
+ {
+ perror ("bind call failed");
+ exit (errno);
+ }
/*
Loop forever (or until a termination message is received)
Receive data through the socket and process it. The processing
@@ -35,16 +50,33 @@
*/
while (1)
{
- recvfrom(socket_descriptor, message, sizeof(message), 0,
+ recv_rc = recvfrom(socket_descriptor, message, sizeof(message), 0,
(struct sockaddr *)&sin, &sin_len);
+ if (recv_rc == -1)
+ {
+ perror ("recvfrom call failed");
+ exit (errno);
+ }
+
printf("Response from server: %s\n", message);
+
if (strncmp(message, "stop", 4) == 0)
{
printf("Sender has told me to end the connection\n");
break;
}
}
- close(socket_descriptor);
+/*
+ Most people don't bother to check the return code
+ returned by the close function
+*/
+ close_rc = close(socket_descriptor);
+ if (close_rc == -1)
+ {
+ perror ("close call failed");
+ exit (errno);
+ }
+
exit (0);
}
--- sender2.c 2000-09-22 20:51:26.000000000 +0800
+++ sender3.c 2000-09-22 20:51:26.000000000 +0800
@@ -58,7 +58,10 @@
perror ("sendto call failed");
exit (errno);
}
+ sleep(3); /* this is the only difference from sender2.c */
}
+
+
/*
Send a termination message
*/
--- receiver2.c 2000-09-22 20:51:26.000000000 +0800
+++ receiver3.c 2000-09-22 20:51:26.000000000 +0800
@@ -6,6 +6,7 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
+#include <fcntl.h>
int port = 6789;
@@ -16,6 +17,7 @@
struct sockaddr_in sin;
int bind_rc, close_rc;
ssize_t recv_rc;
+ long save_file_flags;
printf("Waiting for data from sender\n");
/*
@@ -44,20 +46,41 @@
exit (errno);
}
/*
+ set socket to non-blocking:
+*/
+ save_file_flags = fcntl(socket_descriptor, F_GETFL);
+ printf("file flags are %ld\n", save_file_flags);
+ save_file_flags |= O_NONBLOCK;
+ if (fcntl(socket_descriptor, F_SETFL, save_file_flags) == -1)
+ {
+ perror("trying to set input socket to non-blocking");
+ exit (errno);
+ }
+ printf("file flags are now %ld\n", save_file_flags);
+
+/*
Loop forever (or until a termination message is received)
Receive data through the socket and process it. The processing
in this program is really simple -- printing.
*/
while (1)
{
+ sleep (1); /* wait a moment... */
recv_rc = recvfrom(socket_descriptor, message, sizeof(message), 0,
(struct sockaddr *)&sin, &sin_len);
- if (recv_rc == -1)
+ if (recv_rc == -1 && errno != EAGAIN)
{
- perror ("recvfrom call failed");
+ fprintf(stderr, "errno %d ", errno); perror ("recvfrom call failed");
exit (errno);
}
+ else if (recv_rc == 0 || errno == EAGAIN) /* no data */
+ {
+ printf("no data yet\n");
+ errno = 0; /* clear the error */
+ continue;
+ }
+ errno = 0; /* clear the error */
printf("Response from server: %s\n", message);
if (strncmp(message, "stop", 4) == 0)
专栏文章内容及配图由作者撰写发布,仅供工程师学习之用,如有侵权或者其他违规问题,请联系本站处理。 联系我们
相关推荐
555构成单端双稳态电路图
中国设备业呈两极化 谁搭上本土替代顺风车?
基于软件无线电的扩频通信同步研究
贸泽连续第七年荣获Molex亚太区年度电子目录代理商大奖
555构成两种双稳态电路图
插座表解决方案
基于神经网络模块sn9701开发多变量系统解耦控制器
国网电能表解决方案
由于设备维护和验证问题,中芯国际二季度收入将下降 6%
上海润欣通信诚聘嵌入式软件工程师
富士康将收购夏普的LCD工厂,以扩大在日电动汽车生产
基于神经网络预测器的传感器数据证实技术研究
高速球型摄像头解决方案
Questa One软件使用AI验证复杂的芯片设计
Bourns推出车规级多层压敏电阻系列, 具备先进瞬态能量吸收能力,提供卓越的浪涌保护
单芯片电能表解决方案
全球封测前十大揭晓 中国大陆厂商奋起
求助i2c,eeprom工作原理,小弟要用软件模拟一个i2c控制器?
NVIDIA力推1.6T光模组 业界惊传量产延至1Q26
谁有ccs2.2的中文教程?
请教FTP客户端的问题?
无锡村田电子: 与无锡共同成长、为世界贡献经济文化发展
基于软件无线电技术的数字调幅广播系统
基于神经网络的声测法车辆类型辨识的应用研究
拜登AI禁令被废除,美国升级半导体管制措施
电缆测试的电路图
一个看门狗的电路图
中兴ZTE289手机维修 图2
关于 CAN BUS
瑞萨电子MCU直流无刷电动工具解决方案