企业网站明细费用,仿163ym源码交易平台网站源码,惠州淘宝网站建设,做网站开发能挣钱socket通信之C篇 服务端与客户端简介 socket通信服务端与客户端通信模型通信实战server#xff08;服务端#xff09;创建client#xff08;客户端#xff09;创建 函数详解创建套接字 socket绑定端口bind进入监听状态listen获取客户端连接请求accept接收网络数据read发送数… socket通信之C篇 服务端与客户端简介 socket通信服务端与客户端通信模型通信实战server服务端创建client客户端创建 函数详解创建套接字 socket绑定端口bind进入监听状态listen获取客户端连接请求accept接收网络数据read发送数据write关闭套接字close连接指定服务端connect 服务端与客户端
简介 服务端与客户端是计算机网络通信的两个主要角色在物理上并没有什么区别可以同时在一个设备也可在不同的设备上。只不过在市场上为了性能和更好的提供服务。大部分的服务端与客户端不在同个设备中。 客户端(client)一般指通过应用程序例如手机app电脑软件或浏览器网页向服务器获取资源和数据的计算机或设备。 服务端(server)一般指提供服务的计算机或设备。服务端接收并处理客户端的请求并返回对应的结果。 服务器指服务端所部署的计算机或设备
socket通信
以下均在linux系统中实现socket通信是进程通信的一种方式。以下操作函数的头文件位于socket.h
服务端与客户端通信模型 通信实战
server服务端创建
#include stdio.h
#include sys/socket.h
#include netinet/in.h
#include unistd.h
#include string.hint main()
{int socketfd socket(AF_INET, SOCK_STREAM, 0);if(socketfd 0){printf(creat socket error\n);return -1;}struct sockaddr_in socket_addr;memset(socket_addr, 0, sizeof(socket_addr)); socket_addr.sin_family AF_INET;socket_addr.sin_addr.s_addr htonl(INADDR_ANY);socket_addr.sin_port htons(4017);if(bind(socketfd, (struct sockaddr *)socket_addr, sizeof(socket_addr)) 0){printf(bind port error\n);return -1;}if(listen(socketfd, 5) 0){printf(listen error\n);return -1;}struct sockaddr_in client_addr;int clilen sizeof(struct sockaddr_in);int clifd accept(socketfd, (struct sockaddr*)client_addr, (socklen_t*)clilen);char buf[256] {0};char sendbuf[] hello;while(1){memset(buf, 0, sizeof(buf));read(clifd, buf, 255);printf(recv message is: %s\n, buf);write(clifd, sendbuf, 5);sleep(1);}close(clifd);close(socketfd);return 0;
}client客户端创建
#include stdio.h
#include sys/socket.h
#include netinet/in.h
#include unistd.h
#include string.h
#include arpa/inet.hint main()
{int socketfd socket(AF_INET, SOCK_STREAM, 0);if(socketfd 0){printf(creat socket error\n);return -1;}struct sockaddr_in socket_addr;memset(socket_addr, 0, sizeof(socket_addr)); socket_addr.sin_family AF_INET;socket_addr.sin_addr.s_addr inet_addr(127.0.0.1);socket_addr.sin_port htons(4017);if(connect(socketfd, (struct sockaddr *)socket_addr, sizeof(socket_addr)) 0){printf(bind port error\n);return -1;}char buf[256] {0};char sendbuf[] client msg;while(1){memset(buf, 0, sizeof(buf));read(socketfd, buf, 255);printf(recv message is: %s\n, buf);write(socketfd, sendbuf, 11);sleep(1);}close(socketfd);return 0;
}
函数详解
创建套接字 socket
函数原型
int socket(int domain, int type, int protocol)函数解析 作用 用于创建一个指定协议的sockfd即一个套接字。 例如创建一个tcpipv4的sockfd int socketfd socket(AF_INET, SOCK_STREAM, 0);返回 创建失败返回-1成功返回文件描述符。
参数解析 以下枚举值只列出部分
参数说明枚举domain指定通信域即选择通信用的协议族AF_INET:ipv4 AF_INET6:ipv6type指定套接字类型SOCK_STREAM:提供有序的、可靠的、双向的、基于连接的字节流流式协议。SOCK_DGRAM:固定长度的、无连接的、不可靠的报文传递报式协议protocol具体的一个协议一般写0流式协议默认是TCP报式协议默认是UDP
绑定端口bind
函数原型
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);函数解析 作用 将socket创建的socketfd与地址addr进行绑定。大部分用来绑定端口。一般在于服务端使用如果客户端在需要绑定端口的情况下也可以使用。 例如将刚刚创建的socketfd与本地端口4017进行绑定 struct sockaddr_in socket_addr;
memset(socket_addr, 0, sizeof(socket_addr)); socket_addr.sin_family AF_INET;
socket_addr.sin_addr.s_addr htonl(INADDR_ANY);
socket_addr.sin_port htons(4017);bind(socketfd, (struct sockaddr *)socket_addr, sizeof(socket_addr));返回成功返回0一般端口被其他进程占用时才会返回失败
参数解析
参数说明sockfd创建的套接字sockaddr地址结构体中包含了协议族端口号以及地址ipsocklen_t地址所指向的结构体的地址长度
进入监听状态listen
函数原型
int listen(int sockfd, int backlog);函数解析 作用 让服务端进入监听状态等待客户端的连接。用于服务端的进程。需在accept之前使用 例如 最大监听客户端数量为5 listen(socketfd, 5);返回 成功返回0
参数解析
参数说明sockfd创建的套接字backlog服务端等待连接的最大数量即半连接和全连接最大之和
获取客户端连接请求accept
函数原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);函数解析 作用 获取客户端的连接请求并建立连接 例如 struct sockaddr_in client_addr;
int clilen sizeof(struct sockaddr_in);int clifd accept(socketfd, (struct sockaddr*)client_addr, (socklen_t*)clilen);
返回成功返回客户端的socketfd后期通过该socketfd与此客户端进行通信。失败返回-1
参数解析
参数说明sockfd用于监听的文件描述符addr用于返回监听到的客户端的地址信息addrlenaddr的字节大小
接收网络数据read
函数原型
ssize_t read(int fd, void *buf, size_t count);函数解析 作用 接收网络数据 例如获取从clientfd中接收到的网络数据 char buf[256] {0};
read(clientfd, buf, 256);返回成功返回接收到的网络数据长度失败返回0。 头文件unistd.h
参数解析
参数说明sockfd需要获取数据的对象socketfdbuf接收到的网络数据count限制字节接收长度。当缓冲区长度大于该长度时返回count长度字节;档缓冲区长度小于该长度时返回实际长度的字节
发送数据write
函数原型
ssize_t write(int fd, const void *buf, size_t count);函数解析 作用 用于发送数据 例如 对clientfd发送abc char sendbuf[] “hello”;
write(clientfd, sendbuf, 3);返回成功返回成功写入的字节数失败返回-1 头文件unistd.h
参数解析
参数说明fd需要发送数据的对象socketfdbuf发送的数据count当实际发送数据长度大于count时按count数量字节数发送否则按实际长度发送
读取和写入除了read和write外还有recv和sendrecvmsg和sendmsg等。
关闭套接字close
函数原型
int close(int fd);函数解析 作用 关闭指定套接字 例如 close(clientfd);返回成功返回0
参数解析
参数说明fd需要关闭的套接字
连接指定服务端connect
函数原型
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);注意 客户端使用
函数解析 作用 在tcp中用于跟服务端建立连接而在udp中仅仅是在本地对服务端的IP地址和端口与创建的sockfd进行绑定记录 例如 连接ip地址为127.0.0.1本地回环且端口号为4017的服务端进程 struct sockaddr_in socket_addr;
memset(socket_addr, 0, sizeof(socket_addr)); socket_addr.sin_family AF_INET;
socket_addr.sin_addr.s_addr inet_addr(127.0.0.1);
socket_addr.sin_port htons(4017);connect(sockfd, (struct sockaddr *)socket_addrsizeof(socket_addr));返回成功返回0失败返回-1
inet_addr所在头文件为arpa/inet.h
参数解析
参数说明sockfd用于通信的文件描述符addr客户端所要连接的服务端的地址信息addrlenaddr的内存大小