socket通信
1. 概念
1.1 C/C++中socket
#include <sys/socket.h> int socket(int family, int type, int protocol); //指定期望的通信协议类型,返回的文件描述符和套接字描述符类似,我们称为套接字描述符,简称sockfd
family:协议族
family | 说明 |
AF_INET | IPv4协议 |
AF_INET6 | IPv6 |
AF_LOCAL | Unix域协议 |
AF_ROUTE | 路由套接字 |
AF_KEY | 密钥套接字 |
AF_UNIX | 本地通信 |
type:套接字的类型
type | 说明 |
SOCK_STREAM | 字节流套接字 |
SOCK_DGRAM | 数据报套接字 |
SOCK_SEQPACKET | 有序分组套接字 |
SOCK_RAW | 原始套接字 |
protocol:协议类型的常量或设置为0,以选择给定的family和type组合的系统默认值
protocol | 说明 |
IPPROTO_TCP | TCP传输协议 |
IPPROTO_UDP | UDP传输协议 |
IPPROTO_SCTP | SCTP传输协议 |
1.2 Android应用层socket
2. 本地通信代码(android和Linux的区别)
2.1 android和Linux下socket本地通信的区别
在Linux中的本地通信有两种方式:1.创建socket文件,通过文件与客户端socket通信;2.不创建socket文件
在android中无法创建socket文件(应该可以创建,只是我不知道怎么去创建而已)所以只能使用第二种不创建的方式
服务端示例代码:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <unistd.h> #include <stdlib.h> #include <stddef.h> int main(){ int fd; int client_fd; struct sockaddr_un server_address;// 套接字 char ch_send, ch_recv; int server_len, client_len; int i; memset(&server_address, 0, sizeof(server_address)); //必须删除,如果之前有这个文件,则会报错! unlink("server_socket"); //1. 创建一个socket:本地通信协议;字节流方式; fd = socket(AF_UNIX, SOCK_STREAM, 0); printf("1\n"); //填充套接字 server_address.sun_family = AF_UNIX; //这里是socket文件名,client就是用这个文件来通信 //strcpy (server_address.sun_path, "server_socket"); server_address.sun_path[0]='\0'; strcpy (server_address.sun_path+1, "server_socket"); //server_len = strlen(SERVER_NAME) + offsetof(sockaddr_un, sun_path); //printf("offsetof(struct sockaddr_un, sun_path)=%d\n", offsetof(struct sockaddr_un, sun_path)); server_len = offsetof(struct sockaddr_un, sun_path) + strlen(server_address.sun_path+1)+1; printf("server_len=%d\n", server_len); printf("2\n"); //2. 绑定 bind(fd, (struct sockaddr *)&server_address, server_len); printf("3\n"); //3. 被动接收listen listen (fd, 5); printf("4\n"); //4. 监听accept client_fd = accept(fd, (struct sockaddr *)&server_address, (socklen_t *)&client_len); printf("5\n"); //测试发送接收 for (i = 0, ch_send = '1'; i < 5; i++, ch_send++) { //没数据则会阻塞在这里 printf("阻塞\n"); if (read (client_fd, &ch_recv, 1) == -1) { perror ("read1"); exit (EXIT_FAILURE); } printf ("服务端接收到的数据为: %c\n", ch_recv); sleep (1); //发送数据 if (write (client_fd, &ch_send, 1) == -1) { perror ("read2"); exit (EXIT_FAILURE); } } //关闭客户端socket连接 close (client_fd); unlink("server_socket"); }
客户端示例代码:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <unistd.h> #include <stdlib.h> #include <stddef.h> int main (int argc, char *argv[]) { struct sockaddr_un address; int sockfd; int len; int i, bytes; int result; char ch_recv, ch_send; /*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/ if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror ("socket"); exit (EXIT_FAILURE); } address.sun_family = AF_UNIX; //strcpy (address.sun_path, "server_socket"); address.sun_path[0]='\0'; strcpy (address.sun_path+1, "server_socket"); //len = sizeof (address); len = offsetof(struct sockaddr_un, sun_path) + strlen(address.sun_path+1)+1; /*向服务器发送连接请求*/ result = connect (sockfd, (struct sockaddr *)&address, len); if (result == -1) { printf ("ensure the server is up\n"); perror ("connect"); exit (EXIT_FAILURE); } for (i = 0, ch_send = 'A'; i < 5; i++, ch_send++) { if ((bytes = write(sockfd, &ch_send, 1)) == -1) { /*发消息给服务器*/ perror ("write"); exit (EXIT_FAILURE); } sleep (2); /*休息二秒钟再发一次*/ if ((bytes = read (sockfd, &ch_recv, 1)) == -1) { /*接收消息*/ perror ("read"); exit (EXIT_FAILURE); } printf ("客户端接收到的数据为: %c\n", ch_recv); } close (sockfd); return (0); }
参考资料:
http://docs.huihoo.com/c/linux-c-programming/ch37s04.html
http://blog.csdn.net/ccwwff/article/details/45693469
http://www.xuebuyuan.com/726129.html