Chinaunix首页 | 论坛 | 博客
  • 博客访问: 549604
  • 博文数量: 181
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1498
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-22 15:17
个人简介

用发呆的时间来理清自己的思绪

文章存档

2015年(7)

2014年(134)

2013年(40)

分类: 嵌入式

2014-10-27 22:08:29

    Linux内核中已经把TCP/UDP封装在了协议栈中,从编程的角度来说,就是如何使用这些协议栈的问题了,其中,Linux提供了一种叫socket的特殊文件,其实也是一种特殊的操作系统接口,通过这个接口,我们可以利用Linux内核中的协议栈,因此,对编程来说就会变得比较容易,使用UDP或者TCP仅仅是函数接口传递的参数不同而已,大部分的代码是相同的,自己实现的基于UDP的客户端--服务器如下:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>

  6. /***********************************************************
  7.  * 函数功能:基于UDP实现简单的客户端服务器,客户端给服务器发
  8.  * 数据,服务器负责接收数据并把数据打印在终端。
  9.  * 服务器端实现的基本步骤:
  10.  * 1. 创建套接字
  11.  * 2. 给套接字绑定服务器的端口和IP地址
  12.  * 3. 监听套接字
  13.  * 4. 接收客户端发送的数据
  14.  ***********************************************************/
  15.  
  16. //./server ip port
  17. int main(int argc, const char *argv[])
  18. {
  19.     int n;
  20.     int sockfd;
  21.     char buf[1024];
  22.     struct sockaddr_in server_addr;
  23.     struct sockaddr_in peer_addr;
  24.     socklen_t addrlen = sizeof(struct sockaddr);

  25.     if(argc < 3)
  26.     {
  27.         fprintf(stderr,"Usage : %s \n",argv[0]);
  28.         exit(EXIT_FAILURE);
  29.     }

  30.     //1. 创建套接字
  31.     sockfd = socket(AF_INET,SOCK_DGRAM,0);
  32.     if(sockfd < 0){
  33.         perror("Fail to socket");
  34.         exit(EXIT_FAILURE);
  35.     }

  36.     //2. 给套接字绑定服务器的端口和IP地址
  37.     server_addr.sin_family = AF_INET;
  38.     server_addr.sin_addr.s_addr = inet_addr(argv[1]);
  39.     server_addr.sin_port = htons(atoi(argv[2]));
  40.     //3. 监听套接字,实质上是在等待是否有客户端对该套接字进行请求
  41.     if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
  42.     {
  43.         perror("Fail to bind");
  44.         exit(EXIT_FAILURE);
  45.     }
  46.     
  47.     while(1)
  48.     {
  49.      // 4. 接收客户端发送的数据,其中第三个参数可以获取客户端的端口和IP地址信息
  50.         n = recvfrom(sockfd,buf,sizeof(buf) - 1,0,(struct sockaddr *)&peer_addr,&addrlen);
  51.         buf[n] = '\0';

  52.         //在服务器端打印客户端发送的数据、客户端的端口、IP地址
  53.         printf("-----------------------------\n");
  54.         printf("Port : %d\n",ntohs(peer_addr.sin_port));
  55.         printf("Ip : %s\n",inet_ntoa(peer_addr.sin_addr));
  56.         printf("buf : %s\n",buf);
  57.         printf("-----------------------------\n");
  58.     }

  59.     
  60.     return 0;
  61. }
客户端实现代码如下:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>

  7. /***********************************************************
  8.  * 函数功能:基于UDP实现简单的客户端服务器,客户端给服务器发
  9.  * 数据,服务器负责接收数据并把数据打印在终端。
  10.  * 客户端实现的基本步骤:
  11.  * 1. 创建套接字
  12.  * 2. 给套接字绑定服务器的端口和IP地址
  13.  * 3. 给服务器发送数据
  14.  ***********************************************************/
  15. //./client ip port
  16. int main(int argc, const char *argv[])
  17. {
  18.     int n;
  19.     int sockfd;
  20.     char buf[1024];
  21.     struct sockaddr_in server_addr;
  22.     struct sockaddr_in client_addr;
  23.     struct sockaddr_in peer_addr;
  24.     socklen_t addrlen = sizeof(struct sockaddr);

  25.     //输入参数检查
  26.     if(argc < 3)
  27.     {
  28.         fprintf(stderr,"Usage : %s \n",argv[0]);
  29.         exit(EXIT_FAILURE);
  30.     }

  31.     //创建套接字,注意第二个参数必须是SOCK_DGRAM
  32.     sockfd = socket(AF_INET,SOCK_DGRAM,0);
  33.     if(sockfd < 0){
  34.         perror("Fail to socket");
  35.         exit(EXIT_FAILURE);
  36.     }

  37.     //填充服务器的端口和IP地址,因为要给别的服务器发生数据,至少需要知道两个参数:端口和IP
  38.     server_addr.sin_family = AF_INET;
  39.     server_addr.sin_addr.s_addr = inet_addr(argv[1]);//填充的IP地址必须转化为网络字节序
  40.     server_addr.sin_port = htons(atoi(argv[2]));
  41.     
  42.     //完成从标准输入读取字符,然后发送给服务器。
  43.     while(1)
  44.     {
  45.         printf("input >");
  46.         fgets(buf,sizeof(buf),stdin); //按行读取,包括'\n'
  47.         buf[strlen(buf) - 1] = '\0'; //把读入的'\n''\0'替换,保证buf中的字符串是以'\0'结尾

  48.         //客户端给服务器发送数据,第三个参数表示服务器的地址
  49.         n = sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&server_addr,addrlen);
  50.         if(n < 0){
  51.             perror("Fail to sendto");
  52.             exit(EXIT_FAILURE);
  53.         }
  54.     }

  55.     return 0;
  56. }
测试结果如下:

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/network/udp/udp/server$ ./server 192.168.127.131 8888
  2. -----------------------------
  3. Port : 59438
  4. Ip : 192.168.127.131
  5. Buf : hi
  6. -----------------------------
  7. -----------------------------
  8. Port : 59438
  9. Ip : 192.168.127.131
  10. Buf : i am client
  11. -----------------------------

点击(此处)折叠或打开

  1. ubuntu@ubuntu:~/network/udp/udp/client$ vi client.c
  2. ubuntu@ubuntu:~/network/udp/udp/client$ ./client 192.168.127.131 8888
  3. input >hi
  4. input >i am client
  5. input >

阅读(1398) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~