网站红蓝色配色分析,u9u8网站建设,如何知道网站是否被k,网站开发哪里近期在做的项目中#xff0c;涉及到了进程间数据传输#xff0c;系统的原本实现是通过管道#xff0c;但是原有的实现中两个进程是在同一台机器#xff0c;而且两个进程的关系为父子关系#xff0c;而我们要做的是将其中一个进程移植到服务器上#xff0c;因此两个进程要…近期在做的项目中涉及到了进程间数据传输系统的原本实现是通过管道但是原有的实现中两个进程是在同一台机器而且两个进程的关系为父子关系而我们要做的是将其中一个进程移植到服务器上因此两个进程要分开所以管道必然是不可行的方案而对于其它的进程通信方式FIFO消息队列信号量和共享内存显然也是不可行的。因此采取了通过socket的通信方式即网络套接字用来做数据的传输。接下来将对自己对socket的学习一个整理socket是什么socket的创建绑定发送接收消息过程进行分析同时附带一个简单的代码实例。网络套接字Socket套接字是通信端点的抽象其英文socket即为插座孔的意思。如果两个机子要通信中间要通过一条线这条线的两端要连接通信的双方这条线在每一台机子上的接入点则为socket即为插孔所以在通信前我们在通信的两端必须要建立好这个插孔同时为了保证通信的正确端和端之间的插孔必须要一一对应这样两端便可以正确的进行通信了而这个插孔对应到我们实际的操作系统中就是socket文件我们再创建它之后就会得到一个操作系统返回的对于该文件的描述符然后应用程序可以通过使用套接字描述符访问套接字向其写入输入读出数据。站在更贴近系统的层级去看两个机器间的通信方式无非是要通过运输层的TCP/UDP网络层IP因此socket本质是编程接口(API)对TCP/UDP/IP的封装TCP/UDP/IP也要提供可供程序员做网络开发所用的接口这就是Socket编程接口。Socket的创建#include int socket (int domain, int type, int protocol);创建一个socketint server_sockfd socket(AF_INET, SOCK_STREAM, 0);这样我们便创建了一个socket对于socket接收的参数都有什么意义呢从上面我们可以知道socket是对于底层网络通信的一个封装而对于底层的网络通信也是具备多种类型的。而这些参数则是通过组合来表示各类通信的特征从而建立正确的套接字。domain:通信的特性每个域有自己的地址表示格式AF打头表示地址族(Address family)type套接字的类型进一步确定通信特征。protocol:表示为给定域和套接字类型选择默认协议当对同一域和套接字类型支持多个协议时可以通过该字段来选择一个特定协议通常默认为0.上面设置的socket类型在执行的时候也会有默认的协议类型提供比如SOCK_STREAM就TCP协议。从上面的socket类型中我们看到有SOCK_RAW该种类型SOCK_RAW套接字提供一个数据报接口。通过这个我们可以直接访问下面的网络层绕过TCP/UDP因此我们可以进行制定自己的传输层协议。至此我们的socket已经创建出来了当我们不再使用的时候我们可以调用close函数来将其关闭释放该文件描述符这样便可以得到重新的使用。套接字通信是双向的但是我们可以采用shutdown函数来禁止一个套接字的I/O.#includeint shutdown(int sockfd, int how);how可以用来指定读端口或者是写端口这样我们便可以关闭掉读端或者写端。通信我么已经创建好了Socket接下来要做的就是通过socket进行通信了在两个进程间进行通信首先我们要找到这些进程找到进程也就是能够有这些进程的唯一标示有了这些标示我们才可以确定通信的双方然后进行数据的传输对于一个通信进程的标示所采取的方式是通过一个网络地址也就是IP地址战找到我们要通信的主机然后通过端口号找到相应的服务。网络地址端口号唯一标示了一个我们要通信的目标进程。字节序字节序是处理器架构的特性用来指示像整数这种数据类型的内部如何排序大端和小端因此如果通信双方的处理器架构不同则会导致字节序的不一致的问题出现。最底层的网络协议指定了字节序大端字节序但是应用程序在处理数据时则会遇到字节序不一致的问题。对此系统提供了进行处理器字节序和网络字节序之间实施转换的函数。#include uint32_t htonl(uint32_t hostint32)//主机字节转化为网络字节序uint16_t htons(uint16_t hostint16)uint32_t ntohl(uint32_t netint32)//网络字节序转化为主机字节序unint16_t ntohs(uint16_t netint16)地址格式上面我们已经谈到如何表示一个要通信的进程需要一个网络地址和端口而在系统中如何具体的标示这一特征呢根据之前socket的创建我们知道不同socket对应了不同的通信特征而对于不同的通信特征其地址表示上也有一些差别。这里我们只看一下IPV4因特网域地址的表示结构。struct sockaddr_in { sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr;}sin_family: 通信的的域这里为AF_INETsin_port:通信的端口sin_addr:网络地址套接字和地址关联我们套接字已经创建好了地址结构也已经了解了接下来就是要将套接字和地址进行关联关联的方法则是通过bind函数。#include int bind(int sockfd, const struct sockaddr *addr, socklen_t len);创建地址struct sockaddr_in server_sockaddr;server_sockaddr.sin_family AF_INET;server_sockaddr.sin_port htons(PORT);server_sockaddr.sin_addr.s_addr htonl(INADDR_ANY);socklen_t server_len sizeof(server_sockaddr);bind(server_sockfd, (struct sockaddr*)server_sockaddr, server_len)通过bind函数我们实现了socket和地址的绑定。建立连接socket建立好了地址也绑定好了这个时候我们就可以进行连接了要有一方进行连接的建立通过调用connect函数。#include int connect(int sockfd, const struct sockaddr *addr, socklen_t len);sockfd:这个就是本地端socket描述符如果我们没有赋值系统会默认提供一个值。只有当服务器开启并正常运行我们的连接才能够正常建立。如何让socket接收连接请求呢在另一端我们调用listen方法来接收连接请求。#include int listen(int sockfd, int backlog);sockfd:绑定了地址的socket文件描述符。backlog:服务器负载提示系统进程所要入队的未完成请求数量。通过listen我们得到了连接请求接下来就是建立连接通过函数accept#include int accept(int sockfd, struct sockaddr *restric addr, socklen_t *restrict len);调用accept函数的返回值是套接字文件描述符该描述符连接到调用connect的客户端。一旦服务器调用了listen所用的套接字就能接收连接请求使用accept函数获得连接请求并建立连接。使用accept函数获得连接请求并建立连接。int accept(int sockfd, struct sockaddr *restrict addr, socklent_t *restrict len);当调用accept函数会产生一个新的套接字这个新的套接字和原始套接字有相同的套接类型。这个时候我们可以传入一个指向socket的指针和其大小设置之后调用了accept就会将客户端的地址进行缓冲。数据传输连接已经建立好了由于socket本身都是文件描述符因此接下来就可以调用所read和write来通过套接字通信。对于面向连接的数据传输我们需要的两个函数是send和recv。#include ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags)sockfd:accept返回的socket文件描述符。buf:发送数据bytes发送数据大小flags对于传送数据的一些配置项对于不同的socket类型系统提供了不同的发送方法。#include ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags)具体参数和send类似。socket选项设置对于Socket系统提供了更具体细致化的一些配置选项通过这些配置选项我们可以进行进一步具体的配置。#include int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);sockfd我们要进行配置的socketlevel根据我们选用的协议配置相应的协议编号option选项即为上表最后参数是用来存放返回值实现demo实例server#include #include #include #include #include #include #include #include #include #include #define PORT 22468#define KEY 123#define SIZE 1024int main(){char buf[100];memset(buf,0,100);int server_sockfd,client_sockfd;socklen_t server_len,client_len;struct sockaddr_in server_sockaddr,client_sockaddr;/*create a socket.type is AF_INET,sock_stream*/server_sockfd socket(AF_INET,SOCK_STREAM,0);server_sockaddr.sin_family AF_INET;server_sockaddr.sin_port htons(PORT);server_sockaddr.sin_addr.s_addr htonl(INADDR_ANY);server_len sizeof(server_sockaddr);int on;setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR,on,sizeof(on));/*bind a socket or rename a sockt*/if(bind(server_sockfd, (struct sockaddr*)server_sockaddr, server_len)-1){printf(bind error);exit(1);}if(listen(server_sockfd, 5)-1){printf(listen error);exit(1);}client_len sizeof(client_sockaddr);pid_t ppid,pid;while(1) {if((client_sockfd accept(server_sockfd, (struct sockaddr*)client_sockaddr, client_len)) -1){printf(connect error);exit(1);} else {printf(create connection successfully\n);int error send(client_sockfd, You have conected the server, strlen(You have conected the server), 0);printf(%d\n, error);}}return 0;}client#include #include #include #include #include #include #include #include #include #include #define SERVER_PORT 22468#define MAXDATASIZE 100#define SERVER_IP Your IPint main() {int sockfd, numbytes;char buf[MAXDATASIZE];struct sockaddr_in server_addr;printf(\nclient initialization\n);if ((sockfd socket(AF_INET, SOCK_STREAM, 0)) -1) {perror(socket);exit(1);}server_addr.sin_family AF_INET;server_addr.sin_port htons(SERVER_PORT);server_addr.sin_addr.s_addr inet_addr(SERVER_IP);bzero((server_addr.sin_zero),sizeof(server_addr.sin_zero));if (connect(sockfd, (struct sockaddr *)server_addr,sizeof(struct sockaddr_in)) -1){perror(connect error);exit(1);}while(1) {bzero(buf,MAXDATASIZE);printf(\nBegin receive...\n);if ((numbytes recv(sockfd, buf, MAXDATASIZE, 0)) -1){perror(recv);exit(1);} else if (numbytes 0) {int len, bytes_sent;buf[numbytes] \0;printf(Received: %s\n,buf);printf(Send:);char msg[100];scanf(%s,msg);len strlen(msg);//sent to the serverif(send(sockfd, msg,len,0) -1){perror(send error);}} else {printf(soket end!\n);break;}}close(sockfd);return 0;}总结最近也在看的一个RPC框架thrift定义好我们的接口文件然后可以帮助我们生成两端的桩文件而且实现原理上也不过是通过底层的socket通信做了包装执行相应的调用。socket通信在大三的OS课上写过本文主要目的记录本次学习对于socket知识进行了一个回顾。