在Android手机上学习socket程序
我们都知道Android手机是基于Linux系统的,在没有Linux环境,但是想学习socket编程的同学可以在Android手机中试试,利用ndk编译可执行文件在Android手机中运行。不同于动态链接库so,本文首先使用的是可直接运行的bin程序,类似windows的exe文件。
好了,开始编写手机中的客户端服务器程序了!
首先看服务器:
我们新建一个c文件叫serv.c
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/errno.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #define ERR_EXIT(m) \
- do{ \
- perror(m); \
- exit(EXIT_FAILURE); \
- }while(0)
- int main(void) {
- int listenfd;
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
- if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- ERR_EXIT("socket");
- }
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(5188);
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //表示本机所有地址
- int on = 1;
- if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
- ERR_EXIT("setsockopt");
- }
- //我们在socket编程中,如果服务器端使用bind绑定端口,当服务器程序结束时,再次绑定会出现端口被占用的现象,应该使用REUSEADDR方法解决这个问题。
- //服务器端尽可能使用REUSEADDR,在绑定前尽可能使用setsockopt来设置REUSEADDR套接字选项,使用REUSEADDR选项可以使得不必等待TIME_WAIT状态消失就可以重启服务器。
- if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {
- ERR_EXIT("bind");
- }
- if ((listen(listenfd, SOMAXCONN)) < 0) {
- ERR_EXIT("listen");
- }
- struct sockaddr_in peeraddr;
- socklen_t peerlen = sizeof(peeraddr);
- int conn; //主动套接字
- if ((conn = accept(listenfd, (struct sockaddr*) &peeraddr, &peerlen)) < 0) {
- ERR_EXIT("accept");
- }
- char recvbuf[1024] = { 0 };
- int ret;
- while (1) {
- memset(recvbuf, 0, sizeof(recvbuf));
- ret = read(conn, recvbuf, sizeof(recvbuf));
- fputs(recvbuf, stdout);
- write(conn, recvbuf, ret);
- }
- close(conn);
- close(listenfd);
- }
回射客户端cli.c
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/errno.h>
- #include <netinet/in.h>
- #include <unistd.h>
- #include <arpa/inet.h>
- #define ERR_EXIT(m) \
- do{ \
- perror(m); \
- exit(EXIT_FAILURE); \
- }while(0)
- int main(void) {
- int sock;
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
- if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
- ERR_EXIT("socket");
- }
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(5188);
- servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
- if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
- {
- ERR_EXIT("connect");
- }
- char sendbuf[1024]={0};
- char recvbuf[1024]={0};
- while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL){
- write(sock,sendbuf,strlen(sendbuf));
- read(sock,recvbuf,sizeof(recvbuf));
- fputs(recvbuf,stdout);
- memset(sendbuf,0,sizeof(sendbuf));
- memset(recvbuf,0,sizeof(recvbuf));
- }
- close(sock);
- return 0;
- }
Android.mk文件:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_CFLAGS += -O3 -fvisibility=hidden
- LOCAL_MODULE := serv
- LOCAL_C_INCLUDES := $(LOCAL_PATH)
- LOCAL_SRC_FILES := \
- serv.c \
- LOCAL_LDLIBS := -lz -llog -L$(SYSROOT)/usr/lib
- cmd-strip = $(TOOLCHAIN_PREFIX)strip $1
- include $(BUILD_EXECUTABLE)
- #include $(BUILD_SHARED_LIBRARY)
- #LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_CFLAGS += -O3 -fvisibility=hidden
- LOCAL_MODULE := cli
- LOCAL_C_INCLUDES := $(LOCAL_PATH)
- LOCAL_SRC_FILES := \
- cli.c \
- LOCAL_LDLIBS := -lz -llog -L$(SYSROOT)/usr/lib
- cmd-strip = $(TOOLCHAIN_PREFIX)strip $1
- include $(BUILD_EXECUTABLE)
- #include $(BUILD_SHARED_LIBRARY)
执行ndk-build可以得到编译好的bin,如下如:
- adb push cli /data/data/
- adb push serv /data/data/
把编译好的cli和serv可执行文件push到手机中
- cd /data/data/
- chmod 777 serv
- chmod 777 cli
- ./serv
启动server端
- ./cli
启动客户端
可以看到服务器返回来的数据。
http://blog.csdn.net/bupt073114/article/details/43114223
在Android手机上学习socket程序的更多相关文章
- 在 Android 手机上运行 Python 程序
- xe5 android 手机上使用sqlite [转]
在android手机上怎样使用sqlite数据库,这里用Navigator实现 增删改查. 1.新建firemonkey mobile application 2.选择blank applicatio ...
- 安卓手机上运行 PC-E500 程序
目录 第1章安卓手机上运行 PC-E500 程序 1 1 PockEmul 1 2 下载 1 3 打包BASIC程序 2 4 配置PC-E500模拟器 5 5 载入e50 ...
- 如何在 Android 手机上实现抓包?
如何在 Android 手机上实现抓包? http://www.zhihu.com/question/20467503 我想知道某个应用究竟在数据提交到哪里,提交了什么.网上的教程太复杂,不想麻烦.有 ...
- 在Android手机上获取其它应用的包名及版本
转载请注明出处:http://blog.csdn.net/jason_src/article/details/37757661 获取Android手机上其它应用的包名及版本方法有非常多,能够通过AAP ...
- Android 在Android手机上获取其他应用的包名及版本号
获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...
- 如何在Android手机上进行自动化测试(下)
版权声明:允许转载,但转载必须保留原链接:请勿用作商业或者非法用途 前言 通过阅读本篇教程,你将会了解到: 如何使用Poco对Android原生应用进行测试 Poco支持直接对任何Android原生应 ...
- 如何通过wifi在android手机上安装调试应用
如何通过wifi在android手机上安装调试应用 1. 首先还是要打开手机的usb调试选项,并通过usb线连接手机.2. 然后执行“adb tcpip 5555”,把adb从usb模式切换到tcpi ...
- delphi xe5 android 手机上使用sqlite
本篇我们介绍一下在android手机上怎样使用sqlite数据库,这里用Navigator实现 增删改查. 1.新建firemonkey mobile application 2.选择blank ap ...
随机推荐
- popen:让进程看似文件
popen打开一个指向进程的带缓冲的连接: FILE *fp; fp = popen("ls", "r"); fgets(buf, len, fp); pclo ...
- 解决Linux动态库版本兼容问题
说道“动态库版本兼容”,很多人头脑中首先蹦出的就是“Dll Hell”.啊,这曾经让人头疼的难题.时至今日,这个难题已经很好地解决了. 在进一步讨论之前来思考一个问题:Linux下为什么没有让人头痛的 ...
- POJ 3090 Visible Lattice Points (ZOJ 2777)
http://poj.org/problem?id=3090 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1777 题目大意: ...
- 26、驱动调试之根据oops信息和堆栈确定出错的代码
a.驱动作为模块:1. 根据pc值确定该指令属于内核还是外加的模块pc=0xbf000018 它属于什么的地址?是内核还是通过insmod加载的驱动程序?先判断是否属于内核的地址: 看System.m ...
- 2.3系列系统中不支持SimpleDateFormat作字段被序列化
安卓问题记录:在2.3系列系统中不支持SimpleDateFormat作字段被序列化,使用时需要将SimpleDateFormat作临时变量使用.
- 洛谷 P4013 数字梯形问题
->题目链接 题解: 网络流. #include<cstdio> #include<iostream> #include<queue> #include< ...
- Havel-Hakimi定理 hdu2454 / poj1695 Havel-Hakimi定理
Havel-Hakimi定理 当年一度热门出如今ACM赛场上的算法. 算法定义: Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的. 2.首先介绍一下度序列:若把图 G 全部顶点的度 ...
- UUIDUtils工具类
原理是根据自身的操作系统和电脑硬件生成的一个32位的随机字符串,如果是一台电脑使用的话,一年不会重复,经过java之后貌似编程了36位,多了4个"-",下面是代码实现: impor ...
- sdo_geometry 转 st_geometry
CREATE OR REPLACE FUNCTION sdo2sde(geo SDO_GEOMETRY) RETURN st_geometry IS lx number; --类型 (点.线.面) c ...
- Android组件——使用DrawerLayout仿网易新闻v4.4侧滑菜单
摘要: 转载请注明出处:http://blog.csdn.net/allen315410/article/details/42914501 概述 今天这篇博客将记录一些关于DrawerL ...