本文实现一个简单的UDP小例子,来说明Linux下socket编程之UDP的简单实现。本文主要包括三个部分:服务器端的实现,客服端的实现和通信测试。实现的功能:客服端发送一条消息给服务器端,服务器端把客服端发来的消息给显示出来。
一、服务器端的实现
1、打开一个socket用户服务器
/* 1、打开一个socket */
iSocketServerFd = socket(AF_INET, SOCK_DGRAM, 0); // 网路类型为ipv4,链接类型为udp
2、将上面打开的socket与服务器进行绑定
/* 2、绑定 */
/* 2.1 设置要绑定的服务器端 */
tSocketServerAddr.sin_family = AF_INET; // 网络类型为ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 设置服务器端口
tSocketServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 对服务器端进行绑定 */
iRet = bind(iSocketServerFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
3、接收客服端发送过来的数据
/* 3、接收数据 */
iRecvLen = recvfrom(iSocketServerFd, ucRecvBuf, ARRAY_LENGTH, 0,
(struct sockaddr *)&tSocketClientAddr, &iSockAddrLen);
服务器端实现的完整代码如下所示:
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#define SOCKET_PORT 1234 // 定义socket绑定的端口
#define LISTEN_BACKLOG 10 // 设置服务器最大的监听数量
#define ARRAY_LENGTH 256 // 定义缓冲区的大小
/*
* 接收客服端发送过来的数据,并把它们打印出来
*/
int main(void)
{
int iSocketServerFd; // 定义服务器端的socket文件描述符
int iSocketClientFd; // 定义客服端的socket文件描述符
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iSockAddrLen;
int iRet;
unsigned char ucRecvBuf[ARRAY_LENGTH]; // 定义接收缓冲区
int iRecvLen;
signal(SIGCHLD,SIG_IGN);
/* 1、打开一个socket */
iSocketServerFd = socket(AF_INET, SOCK_DGRAM, 0); // 网路类型为ipv4,链接类型为udp
if(iSocketServerFd == -1)
{
printf("socket error!\n");
return -1;
}
/* 2、绑定 */
/* 2.1 设置要绑定的服务器端 */
tSocketServerAddr.sin_family = AF_INET; // 网络类型为ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 设置服务器端口
tSocketServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 对服务器端进行绑定 */
iRet = bind(iSocketServerFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("bind error!\n");
return -1;
}
while(1)
{
/* 3、接收数据 */
iRecvLen = recvfrom(iSocketServerFd, ucRecvBuf, ARRAY_LENGTH, 0,
(struct sockaddr *)&tSocketClientAddr, &iSockAddrLen);
if(iRecvLen <= 0) // 失败
{
printf("recvfrom error!\n");
close(iSocketServerFd);
return -1;
}
else // 成功,将接收到的数据打印出来
{
ucRecvBuf[iRecvLen] = '\0';
printf("Receive a message from : %s\n", inet_ntoa(tSocketClientAddr.sin_addr));
printf("The message is : %s\n", ucRecvBuf);
}
}
close(iSocketServerFd);
return 0;
}
2.1 先连接再通信
a、打开一个socket用于客服端
/* 1、打开一个socket用于客服端 */
iSocketClientFd = socket(AF_INET, SOCK_DGRAM, 0);
b、连接
/* 2、connect */
/* 2.1 设置链接的服务器端的基本信息 */
tSocketServerAddr.sin_family = AF_INET; // 网络类型为ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 服务器端的网络端口
iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 客服端的ip地址
if(iRet == 0)
{
printf("server ip is not valid!\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 将服务器端和客服端链接起来 */
iRet = connect(iSocketClientFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
c、发送数据
/* 3、将用户的输入发送给服务器端 */
iSendLen = send(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0);
完整的代码如下:
#include
#include /* See NOTES */
#include
#include
#include
#include
#define SOCKET_PORT 1234 // 设置服务器端的端口
#define ARRAY_LENGTH 256 // 设置缓冲区的大小
/*
* 输入一个字符串,发送给服务器端
*/
int main(int argc, char **argv)
{
int iSocketClientFd; // 描述客服端socket的文件描述符
struct sockaddr_in tSocketServerAddr;
int iSockAddrLen;
int iSendLen;
unsigned char ucSendBuf[ARRAY_LENGTH]; // 定义一个缓冲区
int iRet;
if(argc != 2)
{
printf("Usage :\n");
printf("%s \n", argv[0]);
return -1;
}
/* 1、打开一个socket用于客服端 */
iSocketClientFd = socket(AF_INET, SOCK_DGRAM, 0);
if(iSocketClientFd == -1)
{
printf("socket error!\n");
return -1;
}
/* 2、connect */
/* 2.1 设置链接的服务器端的基本信息 */
tSocketServerAddr.sin_family = AF_INET; // 网络类型为ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 服务器端的网络端口
iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 客服端的ip地址
if(iRet == 0)
{
printf("server ip is not valid!\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
/* 2.2 将服务器端和客服端链接起来 */
iRet = connect(iSocketClientFd, (const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iRet == -1)
{
printf("connect error!\n");
return -1;
}
printf("Input a message to %s: \n", argv[1]);
while(1)
{
if(fgets(ucSendBuf, ARRAY_LENGTH, stdin)) // 接收用户的输入
{
/* 3、将用户的输入发送给服务器端 */
iSendLen = send(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0);
if(iSendLen <= 0)
{
printf("send error!\n");
close(iSocketClientFd);
return -1;
}
}
}
close(iSocketClientFd);
return 0;
}
/* 1、打开客服端的socket */
iSocketClientFd = socket(AF_INET, SOCK_DGRAM, 0); // 网络类型为ipv4, 传输类型为udp
b、发送数据
/* 2、强用户端的输入发送给服务器端 */
iSendLen = sendto(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
完整的代码实现如下:
#include
#include /* See NOTES */
#include
#include
#include
#include
#define SOCKET_PORT 1234 // 设置服务器端的网络端口
#define ARRAY_LENGTH 256 // 设置缓冲区的大小
/*
* 从用户端输入一个字符串,并把这个字符串发送给客服端
*/
int main(int argc, char **argv)
{
int iSocketClientFd; // 定义一个表示客服端socket的文件描述符
struct sockaddr_in tSocketServerAddr;
int iSockAddrLen;
int iSendLen;
unsigned char ucSendBuf[ARRAY_LENGTH]; // 定义缓冲区
int iRet;
if(argc != 2)
{
printf("Usage :\n");
printf("%s \n", argv[0]);
return -1;
}
/* 1、打开客服端的socket */
iSocketClientFd = socket(AF_INET, SOCK_DGRAM, 0); // 网络类型为ipv4, 传输类型为udp
if(iSocketClientFd == -1)
{
printf("socket error!\n");
return -1;
}
/* 设置要链接的服务器端的基本信息 */
tSocketServerAddr.sin_family = AF_INET; // 网络类型为ipv4
tSocketServerAddr.sin_port = htons(SOCKET_PORT); // 服务器端的网络端口
iRet = inet_aton(argv[1], &tSocketServerAddr.sin_addr); // 要连接的客服端的ip地址
if(iRet == 0)
{
printf("server ip is not valid!\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iSockAddrLen = sizeof(struct sockaddr);
printf("Input a message to %s: \n", argv[1]);
while(1)
{
if(fgets(ucSendBuf, ARRAY_LENGTH, stdin)) // 接收用户端的输入
{
/* 2、强用户端的输入发送给服务器端 */
iSendLen = sendto(iSocketClientFd, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, iSockAddrLen);
if(iSendLen <= 0)
{
printf("sendto error!\n");
close(iSocketClientFd);
return -1;
}
}
}
close(iSocketClientFd);
return 0;
}
客服端一: