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

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

首先看服务器:

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

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

回射客户端cli.c

  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. #define ERR_EXIT(m) \
  11. do{ \
  12. perror(m); \
  13. exit(EXIT_FAILURE); \
  14. }while(0)
  15. int main(void) {
  16. int sock;
  17. struct sockaddr_in servaddr;
  18. memset(&servaddr, 0, sizeof(servaddr));
  19. if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  20. ERR_EXIT("socket");
  21. }
  22. servaddr.sin_family = AF_INET;
  23. servaddr.sin_port = htons(5188);
  24. servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  25. if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  26. {
  27. ERR_EXIT("connect");
  28. }
  29. char sendbuf[1024]={0};
  30. char recvbuf[1024]={0};
  31. while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL){
  32. write(sock,sendbuf,strlen(sendbuf));
  33. read(sock,recvbuf,sizeof(recvbuf));
  34. fputs(recvbuf,stdout);
  35. memset(sendbuf,0,sizeof(sendbuf));
  36. memset(recvbuf,0,sizeof(recvbuf));
  37. }
  38. close(sock);
  39. return 0;
  40. }

Android.mk文件:

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_CFLAGS += -O3 -fvisibility=hidden
  4. LOCAL_MODULE    := serv
  5. LOCAL_C_INCLUDES := $(LOCAL_PATH)
  6. LOCAL_SRC_FILES := \
  7. serv.c  \
  8. LOCAL_LDLIBS :=  -lz -llog -L$(SYSROOT)/usr/lib
  9. cmd-strip = $(TOOLCHAIN_PREFIX)strip $1
  10. include $(BUILD_EXECUTABLE)
  11. #include $(BUILD_SHARED_LIBRARY)
  12. #LOCAL_PATH := $(call my-dir)
  13. include $(CLEAR_VARS)
  14. LOCAL_CFLAGS += -O3 -fvisibility=hidden
  15. LOCAL_MODULE    := cli
  16. LOCAL_C_INCLUDES := $(LOCAL_PATH)
  17. LOCAL_SRC_FILES := \
  18. cli.c   \
  19. LOCAL_LDLIBS :=  -lz -llog -L$(SYSROOT)/usr/lib
  20. cmd-strip = $(TOOLCHAIN_PREFIX)strip $1
  21. include $(BUILD_EXECUTABLE)
  22. #include $(BUILD_SHARED_LIBRARY)

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

  1. adb push cli /data/data/
  2. adb push serv /data/data/

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

  1. cd /data/data/
  2. chmod 777 serv
  3. chmod 777 cli
  1. ./serv

启动server端

  1. ./cli

启动客户端

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

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

在Android手机上学习socket程序的更多相关文章

  1. 在 Android 手机上运行 Python 程序

  2. xe5 android 手机上使用sqlite [转]

    在android手机上怎样使用sqlite数据库,这里用Navigator实现 增删改查. 1.新建firemonkey mobile application 2.选择blank applicatio ...

  3. 安卓手机上运行 PC-E500 程序

    目录 第1章安卓手机上运行 PC-E500 程序    1 1 PockEmul    1 2 下载    1 3 打包BASIC程序    2 4 配置PC-E500模拟器    5 5 载入e50 ...

  4. 如何在 Android 手机上实现抓包?

    如何在 Android 手机上实现抓包? http://www.zhihu.com/question/20467503 我想知道某个应用究竟在数据提交到哪里,提交了什么.网上的教程太复杂,不想麻烦.有 ...

  5. 在Android手机上获取其它应用的包名及版本

    转载请注明出处:http://blog.csdn.net/jason_src/article/details/37757661 获取Android手机上其它应用的包名及版本方法有非常多,能够通过AAP ...

  6. Android 在Android手机上获取其他应用的包名及版本号

    获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...

  7. 如何在Android手机上进行自动化测试(下)

    版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 前言 通过阅读本篇教程,你将会了解到: 如何使用Poco对Android原生应用进行测试 Poco支持直接对任何Android原生应 ...

  8. 如何通过wifi在android手机上安装调试应用

    如何通过wifi在android手机上安装调试应用 1. 首先还是要打开手机的usb调试选项,并通过usb线连接手机.2. 然后执行“adb tcpip 5555”,把adb从usb模式切换到tcpi ...

  9. delphi xe5 android 手机上使用sqlite

    本篇我们介绍一下在android手机上怎样使用sqlite数据库,这里用Navigator实现 增删改查. 1.新建firemonkey mobile application 2.选择blank ap ...

随机推荐

  1. CYPRESS USB芯片win10驱动

    The ZIP file attached with this knowledge base article contains the CyUSB3.inf and CyUSB3.sys files ...

  2. docker 在运行 aspnetcore 镜像时提示 命令找不到

    不要讲路径映射到镜像中的应用根文件夹 例如默认的 /app

  3. 【u122】迎接仪式

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] LHX教主要来X市指导OI学习工作了.为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路 ...

  4. 【u121】教主的花园

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 教主有着一个环形的花园,他想在花园周围均匀地种上n棵树,但是教主花园的土壤很特别,每个位置适合种的树都 ...

  5. spring里头各种获取ApplicationContext的方法

    为啥写这个文章呢?spring各个版本不同,以及和系统框架套在一起不同,导致获取的方式不同,网络上各种版本,太乱了,写获取方式的人都不写这个获取方式是在本地还是在WEB,在那种应用服务器下,在spri ...

  6. js进阶正则表达式修饰符(i、g、m)(var reg2=/html/gi)

    js进阶正则表达式修饰符(i.g.m)(var reg2=/html/gi) 一.总结 1.正则表达式使用:通过那些支持正则表达式的字符串函数来使用(search.match.replace.spli ...

  7. 百度地图坐标之间的距离php

    function GetDistance($lat1, $lng1, $lat2, $lng2){ define('PI',3.1415926535898); define('EARTH_RADIUS ...

  8. mysql中的触发器和事务的操作

    触发器 语法 创建触发器: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW trigge ...

  9. js进阶正则表达式11RegExp的属性和方法(RegExp的属性和方法,就是RegExp对象.(点)什么的形式)(正则表达式执行之前会被编译)

    js进阶正则表达式11RegExp的属性和方法(RegExp的属性和方法,就是RegExp对象.(点)什么的形式)(正则表达式执行之前会被编译) 一.总结 1. RegExp的属性和方法,就是RegE ...

  10. 小强的HTML5移动开发之路(48)——(小练习)新闻订阅系统【1】

    一.总体设计 二.数据库设计 --新闻类别表 create table news_cate( news_cateid int primary key auto_increment, news_icon ...