• Linux 网络编程


      学习一段时间的linux下的程序编写,着手开发环境的搭建如:安装 arm-linux-gcc交叉编译环境,tftp服务器,smb服务,vncserver服务,nfs服务.深入学习了C语言编程,以及linux进程线程相关方面的知识.见于后期会用到linux的网络传输,这里先着手linux下网络通信方面程序的编写 .

      花了几天的时间终于把linux下 TCP 的通信程序简单写了写,包括 tcp_client.c  和 tcp_server.c  。tcp_client.c 负责发送字符串,tcp_server.c 负责接收。代码如下,程序很简单,和网上的大同小异,但做了修改和优化,代码如下:

    tcp_server.c

     1 #include <stdlib.h> 
     2 #include <stdio.h> 
     3 #include <errno.h> 
     4 #include <string.h> 
     5 #include <netdb.h> 
     6 #include <sys/types.h> 
     7 #include <netinet/in.h> 
     8 #include <sys/socket.h> 
     9 
    10 #define portnumber 8500 
    11 
    12 int main(int argc, char *argv[]) 
    13 { 
    14     int sockfd,new_fd; 
    15     struct sockaddr_in server_addr; 
    16     struct sockaddr_in client_addr; 
    17     int sin_size; 
    18     int nbytes;
    19     char buffer[1024];
    20     
    21 
    22     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP
    23     { 
    24         fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); 
    25         exit(1); 
    26     } 
    27 
    28     bzero(&server_addr,sizeof(struct sockaddr_in)); // 初始化,置0
    29     server_addr.sin_family=AF_INET;                 // Internet
    30     server_addr.sin_addr.s_addr=htonl(INADDR_ANY);  
    31     server_addr.sin_port=htons(portnumber);         
    32     
    33     if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 
    34     { 
    35         fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); 
    36         exit(1); 
    37     } 
    38 
    39     if(listen(sockfd,5)==-1) 
    40     { 
    41         fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); 
    42         exit(1); 
    43     } 
    44           
    45 
    46     printf("start listen...\n");
    47     while(1) 
    48     { 
    49         
    50         sin_size=sizeof(struct sockaddr_in);// This is must be in while()?
    51         printf("waiting for connection ----\n");
    52         if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1) 
    53         { 
    54             fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); 
    55             exit(1); 
    56         } 
    57         fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr)); 
    58         while(1)
    59         {
    60             //if((nbytes=read(new_fd,buffer,1024))==-1) 
    61             nbytes=read(new_fd,buffer,1024);
    62               
    63                 if((nbytes==0)||(nbytes==-1))
    64                  {
    65                 if(nbytes==0)
    66                 {
    67                     printf("The connection is error !\n");
    68                     printf("restart server !\n");
    69                     break;
    70                 }
    71                 else
    72                     fprintf(stderr,"Read Error:%s\n",strerror(errno)); 
    73                 exit(1); 
    74              }
    75                  
    76             buffer[nbytes]='\0';
    77             printf("Server received %i--%s\n",nbytes,buffer);
    78         
    79             //close(new_fd);
    80             printf("continute... !\n");
    81             /* 循环下一个 */
    82         } 
    83     } 
    84 
    85     close(sockfd);   //How to jump here ? 
    86     printf("Close socket !\n");
    87     exit(0); 
    88 }
    89     

    tcp_client.c

     1 #include <stdlib.h> 
     2 #include <stdio.h> 
     3 #include <errno.h> 
     4 #include <string.h> 
     5 #include <netdb.h> 
     6 #include <sys/types.h> 
     7 #include <netinet/in.h> 
     8 #include <sys/socket.h> 
     9 #include <time.h>
    10 #define portnumber 8500 
    11 
    12 int main(int argc, char *argv[]) 
    13 { 
    14     int sockfd;
    15     int nbytes; 
    16     char buffer[1024]; 
    17     struct sockaddr_in server_addr; 
    18     struct hostent *host; 
    19 
    20 
    21     if(argc!=2) 
    22     { 
    23         fprintf(stderr,"Usage:%s hostname \a\n",argv[0]); 
    24         exit(1); 
    25     } 
    26 
    27     if((host=gethostbyname(argv[1]))==NULL) 
    28     { 
    29         fprintf(stderr,"Gethostname error\n"); 
    30         exit(1); 
    31     } 
    32 
    33 
    34     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:Internet;SOCK_STREAM:TCP
    35     { 
    36         fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); 
    37         exit(1); 
    38     } 
    39 
    40 
    41     bzero(&server_addr,sizeof(server_addr)); // 初始化,置0
    42     server_addr.sin_family=AF_INET;          // IPV4
    43     server_addr.sin_port=htons(portnumber);  // (将本机器上的short数据转化为网络上的short数据)端口号
    44     server_addr.sin_addr=*((struct in_addr *)host->h_addr); // IP地址
    45     
    46 
    47     if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) 
    48     { 
    49         fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); 
    50         exit(1); 
    51     } 
    52 
    53 
    54     printf("Please input char:\n");
    55     while(1)
    56     {
    57         //string ->  char *
    58         strcpy(buffer,"Test string to char..");
    59         nbytes=write(sockfd,buffer,strlen(buffer));
    60     
    61         printf("Write string Test string to char..\n"); 
    62         sleep(1);
    63     }
    64 
    65 
    66     /* 结束通讯 */ 
    67     close(sockfd); 
    68     exit(0); 
    69 } 

    为了方便程序的调试,简单写了个Makefile文件

      1 all:tcp_server tcp_client
      2 tcp_server:tcp_server.c
      3         gcc -g tcp_server.c -o tcp_server
      4 tcp_client:tcp_client.c
      5         gcc -g tcp_client.c -o tcp_client

    程序简单介绍, 本程序是面向连建的TCP 通讯程序, 其中 read() 方法是阻塞读, 当连接发生异常时 返回值是 0.所以我在tcp_server.c程序里加了个判断,用以判断连接情况。有时间把本程序改成多线程的。我在程序编写的过程中遇到了printf()无输出的情况,查了一下“因为就算执行printf后只是将内容送到缓冲区,但是你到程序结束里,程序结束便会导致缓冲区刷新,你便看到你到屏幕上有你期望到东西出现了。所以我最 后得到一个这样到结论:printf会把东西送到缓冲区,而如果缓冲区不刷新到话,你便不会在屏幕上看到东西,而能导致缓冲区刷新到情况有这些:1 强制刷新 fflush;2,放到缓冲区到内容中包含\n \r ;3,缓冲区已满;4,需要从缓冲区拿东西到时候,如执行scanf”   。

    2013.7.30 日 ,花了一些时间把 网络通信程序修改成了多线程网络通信程序,多线程的好处是:一个线程的阻塞可以不影响主线程的执行.

    简单包括一些互斥量的创建好使用,和线程的创建

     /*----initialize the mutex---------------*/
     89         pthread_mutex_init(&mutex_r,NULL);
     90         /*------ create the read thread -------- */
     91         ret = pthread_create(&id1, NULL, (void*)read_pthread, NULL);
     92         if (ret)
     93         {
     94                 printf("Create pthread error!\n");
     95                 return -1;
     96         }
     97         printf("start the read_pthread successefully !\n");

    和线程存活的判断

             if(pthread_kill(id1,0)!=0)
    105         {
    106                 printf("read_pthread is stoped .\n");
    107                 /*--must stop the write pthread ----*/
    108                 return -1;
    109         }

    具体便不再赘述.目前已经实现了C#四轴操作端和 arm9 开发板的多线程网络通信:

    操作过程 : 启动linux 端程序,等待TCP连接--> C#操控端连接手柄-->设置网络地址 -->启动通信 --> linux 端成功接收数据.

    博文为本人所写,转载请表明出处, 博客园 :梦工厂2012  Linux 网络编程

  • 相关阅读:
    尝试了一下Flex
    Flash版的拉格朗日插值程序
    关于CSS属性display:none和visible:hidden的区别
    KMaster知识管理平台功能简介
    企业级知识库系统KMaster推荐
    ie6下的location.href错误
    利用Jquery实现http长连接(LongPoll)
    jQuery高亮插件
    当前知识管理系统的焦点问题以及我的一些解决办法
    知识库如何跟其他业务系统结合
  • 原文地址:https://www.cnblogs.com/dreamfactory/p/3138513.html
Copyright © 2020-2023  润新知