本文实现一个简单的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 <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>#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,链接类型为udpif(iSocketServerFd == -1){printf("socket error!\n");return -1;}/* 2、绑定 *//* 2.1 设置要绑定的服务器端 */tSocketServerAddr.sin_family      = AF_INET;          // 网络类型为ipv4tSocketServerAddr.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 <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>#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 <server_ip>\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;         // 网络类型为ipv4tSocketServerAddr.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;
}

2.2 直接进行通信
a、打开socket

/* 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 <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>#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 <server_ip>\n", argv[0]);return -1;}/* 1、打开客服端的socket */iSocketClientFd = socket(AF_INET, SOCK_DGRAM, 0); // 网络类型为ipv4, 传输类型为udpif(iSocketClientFd == -1){printf("socket error!\n");return -1;}/* 设置要链接的服务器端的基本信息 */tSocketServerAddr.sin_family      = AF_INET;          // 网络类型为ipv4tSocketServerAddr.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;
}

三、测试
将上面两种方式实现的客服端都和服务器进行通信测试。服务器端和客服端可以在同一台电脑上也可以在不同的电脑上(必须在同一局域网当中),本文是在同一台电脑上对客服端和服务器端进行测试,测试结果如下:

客服端一:

客服端二:

服务器端:

从上面结果可以看出,服务器和两个客服端都通信成功。

Linux下socket编程之UDP简单实现相关推荐

  1. Linux下Socket编程之UDP原理

    一.设计UDP Server类 人们通常用电话连线来说明TCP协议,而UDP协议,则常常用邮递来做比喻.与TCP有连接的信息传输方式不同,UDP协议被认为是对底层IP协议简单的扩展:协议并不保证每个数 ...

  2. Linux下Socket编程之TCP应用

    现在,我们用前面所构建的socket类,重新设计<Linux下Socket编程之TCP Server端>中echo的服务器,然后设计客户端程序. echo服务器的工作原理很简单: 1.接收 ...

  3. Linux下Socket编程之TCP Server端

    一.建模 绝大部分关于socket编程的教程总是从socket的概念开始讲起的.要知道,socket的初衷是个庞大的体系,TCP/IP只是这个庞大体系下一个很小的子集,而我们真正能用上的更是这个子集中 ...

  4. Linux下Socket编程之TCP原理

    一.Socket异常信息 之所以把对异常信息的介绍放到原理之前讲,是因为由于socket本身的复杂性,导致了产生各种异常的复杂性.我们应该时刻铭记的是,sokcet本身属于系统(OS),是系统对TCP ...

  5. Linux C socket 编程之UDP

    发送方: /*  * File:   main.c  * Author: tianshuai  *  * Created on 2011年11月29日, 下午10:34  *  * 主要实现:发送20 ...

  6. linux下简单的shellfor循环程序,对Linux下shell编程之for循环的实例讲解

    对Linux下shell编程之for循环的实例讲解 linux 下 for 循环中可以使用 break 和 continue 关键字来跳出循环, 和java 用法一致 一.常用for循环结构 #语法一 ...

  7. [深入浅出WP8.1(Runtime)]Socket编程之UDP协议

    13.3 Socket编程之UDP协议 UDP协议和TCP协议都是Socket编程的协议,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议.UDP适用于一次只 ...

  8. 基于Linux的Socket编程之TCP全双工Server-Client聊天程序

    转载:http://blog.csdn.net/apollon_krj/article/details/53437764#0-tsina-1-58570-397232819ff9a47a7b7e80a ...

  9. Linux C socket 编程之TCP

    本文主要是,简单实现tcp连接的两个程序.本文编写,假设读者有socket 编程思想.熟悉C编程. 服务端: #include <stdio.h> #include <stdlib. ...

最新文章

  1. 车联网,挖掘数据价值
  2. UE4 custom depth 自定义深度
  3. TensorFlow全新的数据读取方式:Dataset API入门教程
  4. P1018 乘积最大
  5. python元祖封包_[Day8]遷延蹉跎,來日無多-python終極指南:模組和封包,外掛般的超能力...
  6. Spring Cloud Eureka(三)实现一个高可用的注册中心
  7. IOT(30)---庆科物联网平台架构分析
  8. python - 增强的格式化字符串format函数
  9. java 线程面试题_8道Java多线程面试题,看过后你不会后悔!
  10. 身份证号中提取性别、年龄、年月日的Excel(WPS)公式
  11. 小米手机自带计算机不能用怎么解决,如果小米手机无法进入系统怎么办?
  12. VMware Workstation Pro 12 安装黑苹果问题
  13. 我的大学十年 (转)
  14. springboot+美容院会员管理系统 毕业设计-附源码191740
  15. 从红海里面寻找蓝海,看一个人的思维模式
  16. 【教程】腾讯云轻量应用服务器搭建聊天室
  17. 轩辕剑--资料集(一)
  18. JVM性能监控及调优篇
  19. Office365 - 如何查询email是否发送成功
  20. 618这款秒杀神器Python介绍给你,低调使用哦,因为太赞了

热门文章

  1. dva自定义组件及使用方法
  2. 沸点Java笔试考核
  3. Python全局变量的隐藏“窍门”
  4. 3D游戏设计-智能巡逻兵
  5. 商用机器人底盘的秘密
  6. android 英汉字典,英汉全文字典安卓版
  7. 报错:v-html will override element children 解决方法
  8. 树莓派家用NAS解决方案
  9. keepalived配置,解决vip无法ping通,虚拟服务器端口无法访问的问题
  10. HECTF2021 Reverse wp