• 在Android手机上学习socket程序


    我们都知道Android手机是基于Linux系统的,在没有Linux环境,但是想学习socket编程的同学可以在Android手机中试试,利用ndk编译可执行文件在Android手机中运行。不同于动态链接库so,本文首先使用的是可直接运行的bin程序,类似windows的exe文件。

    好了,开始编写手机中的客户端服务器程序了!

    首先看服务器:

    我们新建一个c文件叫serv.c

    [html] view plain copy
     
    1. #include <sys/socket.h>  
    2. #include <sys/types.h>  
    3. #include <stdio.h>  
    4. #include <stdlib.h>  
    5. #include <string.h>  
    6. #include <sys/errno.h>  
    7. #include <netinet/in.h>  
    8. #include <unistd.h>  
    9. #include <arpa/inet.h>  
    10.   
    11. #define ERR_EXIT(m)   
    12.     do{   
    13.         perror(m);   
    14.         exit(EXIT_FAILURE);   
    15.     }while(0)  
    16.   
    17. int main(void) {  
    18.     int listenfd;  
    19.     struct sockaddr_in servaddr;  
    20.     memset(&servaddr, 0, sizeof(servaddr));  
    21.   
    22.     if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) 0) {  
    23.         ERR_EXIT("socket");  
    24.     }  
    25.     servaddr.sin_family = AF_INET;  
    26.     servaddr.sin_port = htons(5188);  
    27.     servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //表示本机所有地址  
    28.   
    29.     int on = 1;  
    30.     if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) 0) {  
    31.         ERR_EXIT("setsockopt");  
    32.     }  
    33.     //我们在socket编程中,如果服务器端使用bind绑定端口,当服务器程序结束时,再次绑定会出现端口被占用的现象,应该使用REUSEADDR方法解决这个问题。  
    34.     //服务器端尽可能使用REUSEADDR,在绑定前尽可能使用setsockopt来设置REUSEADDR套接字选项,使用REUSEADDR选项可以使得不必等待TIME_WAIT状态消失就可以重启服务器。  
    35.   
    36.     if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) 0) {  
    37.         ERR_EXIT("bind");  
    38.     }  
    39.     if ((listen(listenfd, SOMAXCONN)) 0) {  
    40.         ERR_EXIT("listen");  
    41.     }  
    42.   
    43.     struct sockaddr_in peeraddr;  
    44.     socklen_t peerlen = sizeof(peeraddr);  
    45.     int conn; //主动套接字  
    46.     if ((conn = accept(listenfd, (struct sockaddr*) &peeraddr, &peerlen)) 0) {  
    47.         ERR_EXIT("accept");  
    48.     }  
    49.     char recvbuf[1024] = { 0 };  
    50.     int ret;  
    51.     while (1) {  
    52.         memset(recvbuf, 0, sizeof(recvbuf));  
    53.         ret = read(conn, recvbuf, sizeof(recvbuf));  
    54.         fputs(recvbuf, stdout);  
    55.         write(conn, recvbuf, ret);  
    56.     }  
    57.   
    58.     close(conn);  
    59.     close(listenfd);  
    60. }  



    回射客户端cli.c

    [html] view plain copy
     
    1. #include <sys/socket.h>  
    2. #include <sys/types.h>  
    3. #include <stdio.h>  
    4. #include <stdlib.h>  
    5. #include <string.h>  
    6. #include <sys/errno.h>  
    7. #include <netinet/in.h>  
    8. #include <unistd.h>  
    9. #include <arpa/inet.h>  
    10.   
    11. #define ERR_EXIT(m)   
    12.     do{   
    13.         perror(m);   
    14.         exit(EXIT_FAILURE);   
    15.     }while(0)  
    16.   
    17. int main(void) {  
    18.     int sock;  
    19.     struct sockaddr_in servaddr;  
    20.     memset(&servaddr, 0, sizeof(servaddr));  
    21.   
    22.     if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) 0) {  
    23.         ERR_EXIT("socket");  
    24.     }  
    25.     servaddr.sin_family = AF_INET;  
    26.     servaddr.sin_port = htons(5188);  
    27.     servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");  
    28.   
    29.     if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)  
    30.     {  
    31.         ERR_EXIT("connect");  
    32.     }  
    33.     char sendbuf[1024]={0};  
    34.     char recvbuf[1024]={0};  
    35.     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL){  
    36.         write(sock,sendbuf,strlen(sendbuf));  
    37.         read(sock,recvbuf,sizeof(recvbuf));  
    38.         fputs(recvbuf,stdout);  
    39.         memset(sendbuf,0,sizeof(sendbuf));  
    40.         memset(recvbuf,0,sizeof(recvbuf));  
    41.     }  
    42.     close(sock);  
    43.   
    44. return 0;  
    45. }  


    Android.mk文件:

    [html] view plain copy
     
    1. LOCAL_PATH := $(call my-dir)  
    2.   
    3. include $(CLEAR_VARS)  
    4. LOCAL_CFLAGS += -O3 -fvisibility=hidden  
    5. LOCAL_MODULE    := serv  
    6. LOCAL_C_INCLUDES := $(LOCAL_PATH)  
    7. LOCAL_SRC_FILES :=   
    8.                 serv.c    
    9.                   
    10.                   
    11. LOCAL_LDLIBS :=  -lz -llog -L$(SYSROOT)/usr/lib    
    12. cmd-strip = $(TOOLCHAIN_PREFIX)strip $1  
    13. include $(BUILD_EXECUTABLE)  
    14. #include $(BUILD_SHARED_LIBRARY)  
    15.   
    16.   
    17.   
    18. #LOCAL_PATH := $(call my-dir)  
    19.   
    20. include $(CLEAR_VARS)  
    21. LOCAL_CFLAGS += -O3 -fvisibility=hidden  
    22. LOCAL_MODULE    := cli  
    23. LOCAL_C_INCLUDES := $(LOCAL_PATH)  
    24. LOCAL_SRC_FILES :=   
    25.                 cli.c     
    26.                   
    27.                   
    28. LOCAL_LDLIBS :=  -lz -llog -L$(SYSROOT)/usr/lib    
    29. cmd-strip = $(TOOLCHAIN_PREFIX)strip $1  
    30. include $(BUILD_EXECUTABLE)  
    31. #include $(BUILD_SHARED_LIBRARY)  

    执行ndk-build可以得到编译好的bin,如下如:

    [html] view plain copy
     
    1. adb push cli /data/data/  
    2. adb push serv /data/data/  


    把编译好的cli和serv可执行文件push到手机中

    [html] view plain copy
     
    1. cd /data/data/  
    2. chmod 777 serv  
    3. chmod 777 cli  
    [html] view plain copy
     
    1. ./serv  

    启动server端

    [html] view plain copy
     
    1. ./cli  

    启动客户端


    可以看到服务器返回来的数据。

    http://blog.csdn.net/bupt073114/article/details/43114223

  • 相关阅读:
    打酱油
    一个在线演示代码运行的网站
    java数据结构之枚举
    tomcat ; nginx ;mysql
    restful demo 演示; jquery min1.1;
    rest规范 ; restful 风格; gradel介绍 ; idea安装 ;
    jetty;tomcat;热部署
    web容器 web服务器 servlet/jsp容器 之间的区别和关系是什么?
    jetty;linux 目录结构
    servlet;jsp;cookies;session
  • 原文地址:https://www.cnblogs.com/findumars/p/7995540.html
Copyright © 2020-2023  润新知