本文所写代码是基于linux下的编程
UDP(UserDatagramProtocol)是一个简单的面向消息的传输层协议,尽管UDP提供标头和有效负载的完整性验证(通过校验和),但它不保证向上层协议提供消息传递,并且UDP层在发送后不会保留UDP 消息的状态。因此,UDP有时被称为不可靠的数据报协议。如果需要传输可靠性,则必须在用户应用程序中实现。
使用UDP传输数据时,由应用程序根据需要提供报文到达确认、排序、流量控制等功能。通常情况下,UDP采用实时传输机制和时间戳来传输语音和视频数据。
网络通信三要素: 源 目的 长度
服务器:
①用socket套接字获取句柄fb = socket(xxx,xxx,xxx)
和传参设置相应的通讯模式。
②bind绑定句柄bind(xxx,xxx,xxx)
,把fb句柄和IP,端口绑定起来。
③使用sendto/recvfrom
进行数据的收发。
客服端:
①用socket套接字获取句柄fb = socket(xxx,xxx,xxx)
和传参设置相应的通讯模式。
②connect(xxx,xxx,xxx)
发起连接,需要知道服务器端的ip地址,填充进sockaddr_in结构体里面,发起连接。
③使用send/recv
进行数据的收发。
或者
③不使用connect(xxx,xxx,xxx)
发起连接,用sendto/recvfrom
进行数据的收发。
server.c
/*具体的函数应该包含什么头文件可以在linux中的man手册查找相应的函数所需要的头文件*/
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
/* socket
* bind
* sendto/recvfrom
*/
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
int iSocketServer;
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iRet;
int iAddrLen;
int iRecvLen;
unsigned char ucRecvBuf[1000];
int iClientNum = -1;
iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == iSocketServer)
{
printf("socket error!\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("bind error!\n");
return -1;
}
while (1)
{
iAddrLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
}
close(iSocketServer);
return 0;
}
client.c
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
/* socket
* connect
* send/recv
*/
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
int iRet;
unsigned char ucSendBuf[1000];
int iSendLen;
int iAddrLen;
if (argc != 2)
{
printf("Usage:\n");
printf("%s \n" , argv[0]);
return -1;
}
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
#if 0
iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("connect error!\n");
return -1;
}
#endif
while (1)
{
if (fgets(ucSendBuf, 999, stdin))
{
#if 0
iSendLen = send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0);
#else
iAddrLen = sizeof(struct sockaddr);
iSendLen = sendto(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
#endif
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
}
return 0;
}
开发板ip: 192.168.1.17
虚拟机ip: 192.168.1.11
开发板作为服务器,虚拟机开启两个客服端与开发板进行通讯。