在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

启动客户端



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


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值