在Android手提式有线电话机上读书socket程序,80端
分类:pc28.am神测网

写了五个主次,尝试在80端口监听,结果在实践bind的时候退步了。
程序是那般的:

IPv4套接口地址结构

struct sockaddr_in {

uint8_t  sin_len;4

sa_family_t  sin_family;4

in_port_tsin_port;2

struct in_addrsin_addr;4

char sin_zero[8];8

};

劳务器端

我们都了解Android手提式有线话机是基于Linux系统的,在并未有Linux遭受,但是想学习socket编制程序的同室能够在Android手提式无线电话机中尝试,利用ndk编译可施行文件在Android手机中运作。不一致于动态链接库so,本文首先利用的是可直接运维的bin程序,类似windows的exe文件。

 

通用地址结构

struct sockaddr {

uint8_t  sin_len;

sa_family_t  sin_family;

char sa_data[14];//14

};


步骤

  1. 创制一个socket套接字文件汇报符
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  2. 创办叁个sockaddr_in结构体的变量,并配置相应的参数,然后绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //先清除变量值
    serv_addr.sin_family = AF_INET; //表示使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP地址
    serv_addr.sin_port = htons(1234); //配置通讯端口
    bind(serv_sock, (struct sockaddr)serv_addr, sizeof(serv_addr)); //绑定
    知识点:
    a. AF_INET:表示使用IPv4的IP地址,IPv4的IP地址用AF_INET6
    *
    b. inet_addr()函数:将三个点分十进制IP地址调换为长整型(unsigned long)的变量,127.0.0.1表示本机地址
    c. hton()函数:将整型变量从主机字节顺序调换成互连网字节顺序(高位字节寄存在内部存款和储蓄器的低地址处。)
    d. bind:将套接字serv_sock与IP地址和端口绑定在一齐(存款和储蓄在serv_addr中)
  3. 进去监听状态,等待客商发送伏乞
    listen(serv_sock, 20); //对serv_sock套接字进行监听,20意味着最大允许十九个顾客诉求排队
    让套接字处于筋疲力尽监听状态。所谓被动监听,是指套接字一向处于“睡眠”中,直到客商端发起呼吁才会被“唤醒”
  4. 收起客商端央浼
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, &clnt_addr_size);
    用来接收顾客端的央求。程序一旦推行到 accept() 就能被封堵(暂停止运输营),直到顾客端发起呼吁。
  5. 向顾客端发送数据
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));
  6. 关闭套接字
    close(clnt_sock);
    close(serv_sock);

总体的劳务端socket代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
    //创建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //将套接字和IP、端口绑定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //进入监听状态,等待用户发起请求
    listen(serv_sock, 20);

    //接收客户端请求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    //向客户端发送数据
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));

    //关闭套接字
    close(clnt_sock);
    close(serv_sock);
    return 0;
}

好了,最早编写制定手提式有线电话机中的顾客端服务器程序了!

 sockaddr_in sock_addr;
 memset(&sock_addr, 0, sizeof(sock_addr));
 sock_addr.sin_family = AF_INET;
 sock_addr.sin_addr.s_addr = host_inet_addr;
 sock_addr.sin_port = htons(m_local_port);   //m_local_port=80
 ret = bind( m_socket_fd, (const sockaddr*)&sock_addr, sizeof(sockaddr_in));

服务端

//查看8001端口

netstat -na | grep 8001 


int main(void){

int sockfd=0;

/*socket 成立文件陈说符*/

sockfd=socket(AF_INET,SOCK_STREAM,0);

if(sockfd == -1){

perror("fun socketn");

exit(0);

}

/*bind 绑定地址和端口*/

/*struct sockaddr {

sa_family_t sa_family;

char        sa_data[14];

struct sockaddr_in {

uint8_t  sin_len; 4

sa_family_t  sin_family; 4

in_port_t sin_port; 2

struct in_addr sin_addr; 4

char sin_zero[8]; 8

};

}*/

struct sockaddr_in srvaddr;

srvaddr.sin_family = AF_INET;

srvaddr.sin_port = htons(8001);

srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if( bind(sockfd, (struct sockaddr *) &srvaddr,sizeof(srvaddr)) < 0){

perror("fun bindn");

exit(0);

}

/*listen 开启监听 同有时候监听数据

调用listen之后sockfd产生被动套接字,只好接受链接不能够积极发送

*/

if(listen(sockfd,SOMAXCONN) < 0){

perror("fun listenn");

exit(0);

}

/*accept */

struct sockaddr_in peeraddr;

socklen_t peerlen=sizeof(peeraddr);

unsigned int conn = 0;

conn = accept(sockfd,(struct sockaddr *) &peeraddr,(socklen_t *) &peerlen);

if(conn == -1){

perror("fun acceptn");

exit(0);

}

printf("perradd:%sn perrport:%dn",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));

char revbuf[1024] = {0};

/*read write*/

while(1){

int ret = read(conn,revbuf,sizeof(revbuf));

if(ret == 0){

//收到0数据包表达对方早已关门

printf("对方早就关门n");

exit(0);

}

else if(ret < 0){

perror("读数据退步n");

exit(0);

}

fputs(revbuf,stdout);//服务器收到数量,打字与印刷荧屏

write(conn,revbuf,ret);

}

return 0;

}


客户端

首先看服务器:

ret是-1.
然后将m_local_port改成8080中标了。忽然想起来,系统不允许顾客程序在1-1024端口监听,因为她们是著名端口。
那正是说怎么样才得以在资深端口监听呢?显著小编的机器上从不再80端口运转的次第,所以一定有方法,莫非是本身的程序等级非常不够。
于是乎选用su,换到root客商,结果成功bind.

客户端

int main(void){

int sockfd=0;

/*socket 创造文件叙述符*/

sockfd=socket(AF_INET,SOCK_STREAM,0);

if(sockfd == -1){

perror("fun socketn");

exit(0);

}

/*bind 绑定地址和端口*/

/*struct sockaddr {

sa_family_t sa_family;

char        sa_data[14];

struct sockaddr_in {

uint8_t  sin_len; 4

sa_family_t  sin_family; 4

in_port_t sin_port; 2

struct in_addr sin_addr; 4

char sin_zero[8]; 8

};

}*/

struct sockaddr_in srvaddr;

srvaddr.sin_family = AF_INET;

srvaddr.sin_port = htons(8001);

srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(connect(sockfd,(struct sockaddr *)&srvaddr,sizeof(srvaddr)) < 0){

perror("connect errorn");

exit(0);

}

char revbuf[1024] = {0};

char sendbuf[1024] = {0};

while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL){

//向服务器上写多少

write(sockfd,sendbuf,sizeof(sendbuf));

//从服务器上读数据

read(sockfd,revbuf,sizeof(revbuf));

//打印到荧屏

fputs(revbuf,stdout);

memset(revbuf,0,sizeof(revbuf));

memset(sendbuf,0,sizeof(sendbuf));

}

close(sockfd);

return 0;

}

步骤

  1. 开创三个套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
  2. 创办供给再而三的服务器的sockaddr_in结构体的变量,并配备相应的参数,然后连接
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //各种字节都用0填充
    serv_addr.sin_family = AF_INET; //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //因为大家总是的劳动器端在本机上,所以该地址为本机地址
    serv_addr.sin_port = htons(1234); //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    注:connect向服务器发起呼吁,服务器的IP地址和端口号保存在 sockaddr_in 结构体中。直到劳动器端重回数据,connect才甘休。
  3. 读取服务器端重回的数目
    char bufRecv[100] = {0};
    read(sock, bufRecv, 100);
    printf("Message form server: %sn", bufRecv);
  4. 关闭套接字
    close(sock);

做到的代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
    //创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    //向服务器(特定的IP和端口)发起请求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;            //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //读取服务器传回的数据
    char buffer[40];
    read(sock, buffer, sizeof(buffer)-1);
    printf("Message form server: %sn", buffer);

    //关闭套接字
    close(sock);
    return 0;
}

大家新建三个c文件叫serv.c

笔录一下。

 

 

 

程序是这么的: sockaddr_in sock_addr; memset(sock_addr, 0, sizeof(sock_addr)); sock_a...

[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绑定端口,当服务器程序截止时,再度绑定相会世端口被侵占的情景,应该利用REUSEADDQX56方法消除这一个难点。  
  34.     //服务器端尽大概使用REUSEADDSportage,在绑定前尽量采取setsockopt来设置REUSEADDRAV4套接字选项,使用REUSEADD智跑选项能够使得不必等待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,如下如:

图片 1

 

[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端

 

图片 2

 

[html] view plain copy

 

  1. ./cli  

启航顾客端

图片 3

能够见到服务器重返来的数码。

 

本文由pc28.am发布于pc28.am神测网,转载请注明出处:在Android手提式有线电话机上读书socket程序,80端

上一篇:只是你知道它和Unix分歧吧,操作系统Linux和UNIX的 下一篇:没有了
猜你喜欢
热门排行
精彩图文