免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1701 | 回复: 3
打印 上一主题 下一主题

[C] 串口编译求解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-01-07 15:03 |只看该作者 |倒序浏览
刚接触Linux,老师傅让我用C 在Linux串口程序实现(linux系统函数实现,必须使用多线程)能正常收发AT指令,这个真是一点头绪和方向都没有啊,看网上相关的写了半天才写了个打开USB然后配置串口,再往下什么读写怎么弄一点都不会啊,百度什么的都是相同的文章,或者写的对我这个初学者来说看不懂,想借鉴也不会啊。。有大神指教或者帮我编写下嘛



#include<stdio.h>      /*标准输入输出定义*/  
#include<stdlib.h>     /*标准函数库定义*/  
#include<unistd.h>     /*Unix 标准函数定义*/  
#include<sys/types.h>   
#include<sys/stat.h>     
#include<fcntl.h>      /*文件控制定义*/  
#include<termios.h>    /*PPSIX 终端控制定义*/  
#include<errno.h>      /*错误号定义*/  
#include<string.h>  
#define FALSE  -1  
#define TRUE   0

int main(int argc,char** argv)  
{  
   int fd;
   char read_buf[256];
   char write_buf[256];
   struct termios opt;
   fd = open( "/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);  
   if (FALSE == fd)  
   {  
   perror("Can't Open Serial Port";  
   return(FALSE);  
   }
   else
   printf("open ttyUSB0 success!\n";
   cfsetispeed(&opt,B115200);
   cfsetospeed(&opt,B115200);
   opt.c_cflag&=CS8;
   opt.c_cflag&=~CSIZE;
   opt.c_cflag|=~CSTOPB;
   opt.c_cflag&=~PARENB;
   tcsetattr(fd,TCSANOW,&opt);
}

论坛徽章:
36
CU大牛徽章
日期:2013-09-18 15:24:20NBA常规赛纪念章
日期:2015-05-04 22:32:03牛市纪念徽章
日期:2015-07-24 12:48:5515-16赛季CBA联赛之辽宁
日期:2016-03-30 09:26:4715-16赛季CBA联赛之北控
日期:2016-03-30 11:26:2315-16赛季CBA联赛之广夏
日期:2016-05-20 15:46:5715-16赛季CBA联赛之吉林
日期:2016-05-24 11:38:0615-16赛季CBA联赛之青岛
日期:2016-05-30 13:41:3215-16赛季CBA联赛之同曦
日期:2016-06-23 16:41:052015年亚洲杯之巴林
日期:2015-02-03 15:05:04CU大牛徽章
日期:2013-09-18 15:24:52CU十二周年纪念徽章
日期:2013-10-24 15:46:53
2 [报告]
发表于 2016-01-07 15:25 |只看该作者
多线程用来干嘛?
==========
给个例子你吧
#tip /dev/ttyUSB0
#>at+csq
.......
==========
源码:
  1. /*****************************************************************************/

  2. /*
  3. *      tip.c -- simple tip/cu program.
  4. *
  5. *      (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
  6. *      (C) Copyright 2002, SnapGear Inc (www.snapgear.com)
  7. *      (C) Copyright 2000-2001, Lineo Inc. (www.lineo.com)
  8. *
  9. *      Modified 5 May 2000, Rick Stevenson.
  10. *              Added -f option to pass XON/XOFF characters through
  11. *              to remote end.
  12. *
  13. *      Modified 020131, Heiko Degenhardt (heiko.degenhardt@sentec-elektronik.de)
  14. *              - Added signal handler to restore the termios
  15. *              - Introduced SaveRemoteTermIOs/RestoreRemoteTermIOs to
  16. *                correctly leave the remote side.
  17. *              - Introduced a global var that holds the file pointer
  18. *                (FIXME: Don't know if a global var is the right thing!)
  19. *
  20. *      Modified March 8, 2004, Mike Risi.
  21. *      Added call to cfmakeraw in setlocaltermios().  The comment above
  22. *      setlocaltermios() claimed this was done, but it wasn't.
  23. *
  24. */

  25. /*****************************************************************************/

  26. #include <stdio.h>
  27. #include <unistd.h>
  28. #include <stdlib.h>
  29. #include <fcntl.h>
  30. #include <getopt.h>
  31. #include <errno.h>
  32. #include <sys/types.h>
  33. #include <sys/termios.h>
  34. #include <sys/time.h>
  35. #include <string.h>
  36. #include <signal.h>

  37. #ifndef EMBED
  38. #include <sys/select.h>
  39. #endif

  40. /*****************************************************************************/

  41. char *version = "1.0.2a";

  42. /*****************************************************************************/

  43. /*
  44. *      Define some parity flags, internal use only.
  45. */
  46. #define PARITY_NONE     0
  47. #define PARITY_EVEN     1
  48. #define PARITY_ODD      2

  49. /*
  50. *      Default port settings.
  51. */
  52. int             clocal;
  53. int             hardware;
  54. int             software;
  55. int             passflow;
  56. int             parity = PARITY_NONE;
  57. int             databits = 8;
  58. unsigned int    baud = 9600;

  59. int             translate;
  60. int             ocasemode, icasemode;

  61. char            *devname;
  62. int             gotdevice;
  63. int             rfd;

  64. /*
  65. *      Working termios settings.
  66. */
  67. struct termios  savetio_local;
  68. struct termios  savetio_remote;

  69. /*
  70. *      Signal handling.
  71. */
  72. struct sigaction        sact;

  73. /*
  74. *      Temporary buffer to use when working.
  75. */
  76. unsigned char   ibuf[512];
  77. unsigned char   obuf[1024];

  78. /*****************************************************************************/

  79. /*
  80. *      Baud rate table for baud rate conversions.
  81. */
  82. typedef struct baudmap {
  83.         unsigned int    baud;
  84.         unsigned int    flag;
  85. } baudmap_t;


  86. struct baudmap  baudtable[] = {
  87.         { 0, B0 },
  88.         { 50, B50 },
  89.         { 75, B75 },
  90.         { 110, B110 },
  91.         { 134, B134 },
  92.         { 150, B150 },
  93.         { 200, B200 },
  94.         { 300, B300 },
  95.         { 600, B600 },
  96.         { 1200, B1200 },
  97.         { 1800, B1800 },
  98.         { 2400, B2400 },
  99.         { 4800, B4800 },
  100.         { 9600, B9600 },
  101.         { 19200, B19200 },
  102.         { 38400, B38400 },
  103.         { 57600, B57600 },
  104.         { 115200, B115200 },
  105.         { 230400, B230400 },
  106.         { 460800, B460800 }
  107. };

  108. #define NRBAUDS         (sizeof(baudtable) / sizeof(struct baudmap))

  109. /*****************************************************************************/

  110. /*
  111. *      Verify that the supplied baud rate is valid.
  112. */

  113. int baud2flag(unsigned int speed)
  114. {
  115.         int     i;

  116.         for (i = 0; (i < NRBAUDS); i++) {
  117.                 if (speed == baudtable[i].baud)
  118.                         return(baudtable[i].flag);
  119.         }
  120.         return(-1);
  121. }

  122. /*****************************************************************************/

  123. void restorelocaltermios(void)
  124. {
  125.         if (tcsetattr(1, TCSAFLUSH, &savetio_local) < 0) {
  126.                 fprintf(stderr, "ERROR: ioctl(TCSETA) failed, errno=%d\n",
  127.                         errno);
  128.                 exit(0);
  129.         }
  130. }

  131. /*****************************************************************************/

  132. void savelocaltermios(void)
  133. {
  134.         if (tcgetattr(1, &savetio_local) < 0) {
  135.                 fprintf(stderr, "ERROR: ioctl(TCGETA) failed, errno=%d\n",
  136.                         errno);
  137.                 exit(0);
  138.         }
  139. }

  140. /*****************************************************************************/

  141. void restoreremotetermios(void)
  142. {
  143.         if (tcsetattr(rfd, TCSAFLUSH, &savetio_remote) < 0) {
  144.                 fprintf(stderr, "ERROR: ioctl(TCSETA) failed, errno=%d\n",
  145.                         errno);
  146.                 exit(0);
  147.         }
  148. }

  149. /*****************************************************************************/

  150. void saveremotetermios(void)
  151. {
  152.         if (tcgetattr(rfd, &savetio_remote) < 0) {
  153.                 fprintf(stderr, "ERROR: ioctl(TCGETA) failed, errno=%d\n",
  154.                         errno);
  155.                 exit(0);
  156.         }
  157. }

  158. /*****************************************************************************/

  159. /*
  160. *      Set local port to raw mode, no input mappings.
  161. */

  162. int setlocaltermios()
  163. {
  164.         struct termios  tio;

  165.         if (tcgetattr(1, &tio) < 0) {
  166.                 fprintf(stderr, "ERROR: ioctl(TCGETA) failed, errno=%d\n",
  167.                         errno);
  168.                 exit(1);
  169.         }

  170.     /* make the local port raw */
  171.     cfmakeraw(&tio);

  172.         if (passflow)
  173.                 tio.c_iflag &= ~(ICRNL|IXON);
  174.         else
  175.                 tio.c_iflag &= ~ICRNL;
  176.         tio.c_lflag = 0;
  177.         tio.c_cc[VMIN] = 1;
  178.         tio.c_cc[VTIME] = 0;

  179.         if (tcsetattr(1, TCSAFLUSH, &tio) < 0) {
  180.                 fprintf(stderr, "ERROR: ioctl(TCSETA) failed, errno=%d\n",
  181.                         errno);
  182.                 exit(1);
  183.         }
  184.         return(0);
  185. }

  186. /*****************************************************************************/

  187. /*
  188. *      Set up remote (connect) port termio settings according to
  189. *      user specification.
  190. */

  191. int setremotetermios()
  192. {
  193.         struct termios  tio;

  194.         memset(&tio, 0, sizeof(tio));
  195.         tio.c_cflag = CREAD | HUPCL | baud2flag(baud);

  196.         if (clocal)
  197.                 tio.c_cflag |= CLOCAL;

  198.         switch (parity) {
  199.         case PARITY_ODD:        tio.c_cflag |= PARENB | PARODD; break;
  200.         case PARITY_EVEN:       tio.c_cflag |= PARENB; break;
  201.         default:                break;
  202.         }

  203.         switch (databits) {
  204.         case 5:         tio.c_cflag |= CS5; break;
  205.         case 6:         tio.c_cflag |= CS6; break;
  206.         case 7:         tio.c_cflag |= CS7; break;
  207.         default:        tio.c_cflag |= CS8; break;
  208.         }

  209.         if (software)
  210.                 tio.c_iflag |= IXON | IXOFF;
  211.         if (hardware)
  212.                 tio.c_cflag |= CRTSCTS;

  213.         tio.c_cc[VMIN] = 1;
  214.         tio.c_cc[VTIME] = 0;

  215.         if (tcsetattr(rfd, TCSAFLUSH, &tio) < 0) {
  216.                 fprintf(stderr, "ERROR: ioctl(TCSETS) failed, errno=%d\n",
  217.                         errno);
  218.                 exit(1);
  219.         }
  220.         return(0);
  221. }

  222. /*****************************************************************************/

  223. void SigHandler(int signal)
  224. {
  225.         printf("\n\nGot signal %i!\n", signal);
  226.         printf("Cleaning up...\n");
  227.         restorelocaltermios();
  228.         restoreremotetermios();
  229.         close(rfd);
  230.         printf("Done.\n\n");
  231.         exit(1);
  232. }

  233. /*****************************************************************************/

  234. /*
  235. *      Code to support 5bit translation to ascii.
  236. *      Whacky 5 bit system used on some older teletype equipment.
  237. */
  238. unsigned char   ascii2code[128] = {
  239.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a,
  240.         0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x00, 0x00,
  241.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  242.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  243.         0x04, 0x00, 0x00, 0x00, 0x85, 0x96, 0x00, 0x94,
  244.         0x97, 0x89, 0x00, 0x91, 0x86, 0x98, 0x87, 0x97,
  245.         0x8d, 0x9d, 0x99, 0x90, 0x8a, 0x81, 0x95, 0x9c,
  246.         0x8c, 0x83, 0x8e, 0x00, 0x00, 0x8f, 0x00, 0x93,
  247.         0x8b, 0x18, 0x13, 0x0e, 0x12, 0x10, 0x16, 0x0a,
  248.         0x05, 0x0c, 0x1a, 0x1e, 0x09, 0x07, 0x06, 0x03,
  249.         0x0d, 0x1d, 0x0a, 0x14, 0x01, 0x1c, 0x0f, 0x19,
  250.         0x17, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
  251.         0x00, 0x18, 0x13, 0x0e, 0x12, 0x10, 0x16, 0x0a,
  252.         0x05, 0x0c, 0x1a, 0x1e, 0x09, 0x07, 0x06, 0x03,
  253.         0x0d, 0x1d, 0x0a, 0x14, 0x01, 0x1c, 0x0f, 0x19,
  254.         0x17, 0x15, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00,
  255. };

  256. unsigned char   lower2ascii[32] = {
  257.         0x00, 0x74, 0x0d, 0x6f, 0x20, 0x68, 0x6e, 0x6d,
  258.         0x0a, 0x6c, 0x72, 0x67, 0x69, 0x70, 0x63, 0x76,
  259.         0x65, 0x7a, 0x64, 0x62, 0x73, 0x79, 0x66, 0x78,
  260.         0x61, 0x77, 0x6a, 0x80, 0x75, 0x71, 0x6b, 0x80,
  261. };

  262. unsigned char   upper2ascii[32] = {
  263.         0x00, 0x35, 0x0d, 0x39, 0x20, 0x24, 0x2c, 0x2e,
  264.         0x0a, 0x29, 0x34, 0x40, 0x38, 0x30, 0x3a, 0x3d,
  265.         0x33, 0x2b, 0x00, 0x3f, 0x27, 0x36, 0x25, 0x2f,
  266.         0x2d, 0x32, 0x07, 0x80, 0x37, 0x31, 0x28, 0x80,
  267. };

  268. int translateread(unsigned char *ip, unsigned char *op, int n)
  269. {
  270.         unsigned char   *sop, c;
  271.         int             i;

  272.         for (sop = op, i = 0; (i < n); i++) {
  273.                 c = *ip++;
  274.                 if (c == 0x1f)
  275.                         icasemode = 0;
  276.                 else if (c == 0x1b)
  277.                         icasemode = 1;
  278.                 else
  279.                         c = (icasemode) ? upper2ascii[c] : lower2ascii[c];
  280.                 *op++ = c;
  281.         }
  282.         return(op - sop);
  283. }

  284. int translatewrite(unsigned char *ip, unsigned char *op, int n)
  285. {
  286.         unsigned char   *sop, c;
  287.         int             i;

  288.         for (sop = op, i = 0; (i < n); i++) {
  289.                 c = *ip++;
  290.                 c = ascii2code[c & 0x7f];
  291.                 if (ocasemode && ((c & 0x80) == 0)) {
  292.                         *op++ = 0x1f;
  293.                         ocasemode = 0;
  294.                 }
  295.                 if ((ocasemode == 0) && (c & 0x80)) {
  296.                         *op++ = 0x1b;
  297.                         ocasemode = 1;
  298.                 }
  299.                 *op++ = (c & 0x1f);
  300.         }
  301.         return(op - sop);
  302. }

  303. /*****************************************************************************/

  304. /*
  305. *      Do the connection session. Pass data between local and remote
  306. *      ports.
  307. */

  308. int loopit()
  309. {
  310.         fd_set  infds;
  311.         char    *bp;
  312.         int     maxfd, n;
  313.         int     partialescape = 0;

  314.         maxfd = rfd + 1;

  315.         for (;;) {
  316.                 FD_ZERO(&infds);
  317.                 FD_SET(1, &infds);
  318.                 FD_SET(rfd, &infds);

  319.                 if (select(maxfd, &infds, NULL, NULL, NULL) < 0) {
  320.                         fprintf(stderr, "ERROR: select() failed, errno=%d\n",
  321.                                 errno);
  322.                         exit(1);
  323.                 }

  324.                 if (FD_ISSET(rfd, &infds)) {
  325.                         bp = ibuf;
  326.                         if ((n = read(rfd, ibuf, sizeof(ibuf))) < 0) {
  327.                                 fprintf(stderr, "ERROR: read(fd=%d) failed, "
  328.                                         "errno=%d\n", rfd, errno);
  329.                                 exit(1);
  330.                         }
  331.                         if (n == 0)
  332.                                 break;
  333.                         if (translate) {
  334.                                 n = translateread(ibuf, obuf, n);
  335.                                 bp = obuf;
  336.                         }
  337.                         if (write(1, bp, n) < 0) {
  338.                                 fprintf(stderr, "ERROR: write(fd=%d) failed, "
  339.                                         "errno=%d\n", 1, errno);
  340.                                 exit(1);
  341.                         }
  342.                 }

  343.                 if (FD_ISSET(1, &infds)) {
  344.                         bp = ibuf;
  345.                         if ((n = read(1, ibuf, sizeof(ibuf))) < 0) {
  346.                                 fprintf(stderr, "ERROR: read(fd=%d) failed, "
  347.                                         "errno=%d\n", 1, errno);
  348.                                 exit(1);
  349.                         }

  350.                         if (n == 0)
  351.                                 break;
  352.                         if ((n == 1) && (*bp == 0x1d))
  353.                                 break;
  354.                         if ((n == 1) && (*bp == 0x1))
  355.                                 break;
  356.                         if (partialescape) {
  357.                                 if (*bp == '.')
  358.                                         break;
  359.                                 partialescape = 0;
  360.                         } else {
  361.                                 partialescape = ((n == 1) && (*bp == '~')) ? 1 : 0;
  362.                         }

  363.                         if (translate) {
  364.                                 n = translatewrite(ibuf, obuf, n);
  365.                                 bp = obuf;
  366.                         }


  367.                         if (write(rfd, bp, n) < 0) {
  368.                                 fprintf(stderr, "ERROR: write(rfd=%d) failed, "
  369.                                         "errno=%d\n", rfd, errno);
  370.                                 exit(1);
  371.                         }
  372.                 }
  373.         }
  374.         return (0);
  375. }

  376. /*****************************************************************************/

  377. void usage(FILE *fp, int rc)
  378. {
  379.         fprintf(fp, "Usage: tip [-h?eonxrct5678] [-s speed] "
  380.                 "[-l device] [device]\n\n"
  381.                 "\t-h?\tthis help\n"
  382.                 "\t-5\t5 data bits\n"
  383.                 "\t-6\t6 data bits\n"
  384.                 "\t-7\t7 data bits\n"
  385.                 "\t-8\t8 data bits (default)\n"
  386.                 "\t-e\teven parity\n"
  387.                 "\t-o\todd parity\n"
  388.                 "\t-n\tno parity (default)\n"
  389.                 "\t-s\tbaud rate (default 9600)\n"
  390.                 "\t-c\tuse clocal mode (no disconnect)\n"
  391.                 "\t-t\ttranslate 5 bit codes to ascii\n"
  392.                 "\t-l\tdevice to use\n"
  393.                 "\t-x\tuse software flow (xon/xoff)\n"
  394.                 "\t-r\tuse hardware flow (rts/cts)\n"
  395.                 "\t-f\tpass xon/xoff flow control to remote\n");
  396.         exit(rc);
  397. }

  398. /*****************************************************************************/

  399. int main(int argc, char *argv[])
  400. {
  401.         int     c;

  402.         gotdevice = 0;

  403.         while ((c = getopt(argc, argv, "eonxrctf5678h?s:l:")) > 0) {
  404.                 switch (c) {
  405.                 case 'v':
  406.                         printf("%s: version %s\n", argv[0], version);
  407.                         exit(0);
  408.                 case '5':
  409.                         databits = 5;
  410.                         break;
  411.                 case '6':
  412.                         databits = 6;
  413.                         break;
  414.                 case '7':
  415.                         databits = 7;
  416.                         break;
  417.                 case '8':
  418.                         databits = 8;
  419.                         break;
  420.                 case 't':
  421.                         translate++;
  422.                         break;
  423.                 case 'r':
  424.                         hardware++;
  425.                         break;
  426.                 case 'x':
  427.                         software++;
  428.                         break;
  429.                 case 'f':
  430.                         passflow++;
  431.                         break;
  432.                 case 'o':
  433.                         parity = PARITY_ODD;
  434.                         break;
  435.                 case 'e':
  436.                         parity = PARITY_EVEN;
  437.                         break;
  438.                 case 'n':
  439.                         parity = PARITY_NONE;
  440.                         break;
  441.                 case 's':
  442.                         baud = atoi(optarg);
  443.                         if (baud2flag(baud) < 0) {
  444.                                 fprintf(stderr,
  445.                                         "ERROR: baud speed specified %d\n",
  446.                                         baud);
  447.                                 exit(1);
  448.                         }
  449.                         break;
  450.                 case 'c':
  451.                         clocal++;
  452.                         break;
  453.                 case 'l':
  454.                         gotdevice++;
  455.                         devname = optarg;
  456.                         break;
  457.                 case 'h':
  458.                 case '?':
  459.                         usage(stdout, 0);
  460.                         break;
  461.                 default:
  462.                         fprintf(stderr, "ERROR: unkown option '%c'\n", c);
  463.                         usage(stderr, 1);
  464.                         break;
  465.                 }
  466.         }

  467.         if ((optind < argc) && (gotdevice == 0)) {
  468.                 gotdevice++;
  469.                 devname = argv[optind++];
  470.         }

  471.         if (gotdevice == 0) {
  472.                 fprintf(stderr, "ERROR: no device specified\n");
  473.                 usage(stderr, 1);
  474.         }
  475.         if (optind < argc) {
  476.                 fprintf(stderr, "ERROR: too many arguments\n");
  477.                 usage(stderr, 1);
  478.         }

  479.         /*
  480.          *      Check device is real, and open it.
  481.          */
  482.         if ((rfd = open(devname, (O_RDWR | O_NDELAY))) < 0) {
  483.                 fprintf(stderr, "ERROR: failed to open %s, errno=%d\n",
  484.                         devname, errno);
  485.                 exit(0);
  486.         }

  487.         savelocaltermios();
  488.         setlocaltermios();
  489.         saveremotetermios();
  490.         setremotetermios();

  491.         /*
  492.          *      Set the signal handler to restore the old termios .
  493.          */
  494.         sact.sa_handler = SigHandler;
  495.         sigaction(SIGHUP, &sact, NULL);
  496.         sigaction(SIGINT, &sact, NULL);
  497.         sigaction(SIGQUIT, &sact, NULL);
  498.         sigaction(SIGPIPE, &sact, NULL);
  499.         sigaction(SIGTERM, &sact, NULL);

  500.         printf("Connected.\n");
  501.         loopit();

  502.         restoreremotetermios();
  503.         restorelocaltermios();
  504.         close(rfd);
  505.         printf("Disconnected.\n");
  506.         exit(0);
  507. }

  508. /*****************************************************************************/
复制代码

论坛徽章:
0
3 [报告]
发表于 2016-01-07 15:39 |只看该作者
看了一眼,眼前好黑= =  啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊要死要死啊回复 2# idi0t


   

论坛徽章:
0
4 [报告]
发表于 2016-01-07 15:50 |只看该作者
我就是想写一个波特率什么的既定好的,也不用像minicom那样需要重新设置波特率啊什么的,这些都是固定的一个值,因为我用的对象也就一个吗,老师傅的意思就是让我自己写一个串口工具来用来发AT指令给模块,然后看返回值,看着好晕啊, 人生一片灰暗啊= = 回复 2# idi0t


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP