您的位置:首页 > 教育 > 锐评 > 领动云建站_景观设计学_广告平台网站有哪些_百度咨询

领动云建站_景观设计学_广告平台网站有哪些_百度咨询

2025/6/12 8:32:03 来源:https://blog.csdn.net/2301_79532069/article/details/144251712  浏览:    关键词:领动云建站_景观设计学_广告平台网站有哪些_百度咨询
领动云建站_景观设计学_广告平台网站有哪些_百度咨询

目录

一、创建套接字

二、绑定套接字

示例

三、监听套接字

四、等待套接字

五、服务器端示例

六、连接套接字

七、客户端示例

八、Send和Recv


C/S模式:Client客户端、Server服务器

TCP编程基于socket套接字实现,因此也习惯称为Socket编程

一、创建套接字

#include <sys/types.h>
#include <sys/socket.h>//创建套接字
int socket(int doman, int type, int protocol)params: domain:  AF_INET----IPV4AF_INET6---IPV6AF_UNIX,AF_LOCAL--本地通信  此外还有AF_NETLINK用于做设备驱动/内核用户间通信、AF_PACKET原始套接字type:    SOCK_STREAM 流式套接字 唯一对应TCPSOCK_DGRAM  数据报套接字 唯一对应UDPSOCK_RAW    原始套接字 protocol:一般填0return:成功时返回fd,出错时返回-1

二、绑定套接字

#include <sys/types.h>
#include <sys/socket.h>//绑定套接字----服务器使用
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)params:	addr:    //配置完sockaddr_in(见下)后---强转为sockaddr指针addrlen: //return:成功返回0,出错返回-1//补充
struct sockaddr{ //通用结构体 仅作为一种模型,实际上要将下面的结构体配置完成后强转为此结构体sa_family_t sa_family;  //2B 协议族char        sa_data[14];//IP+端口号
}
struct sockaddr_in{	//基于Internet通信的结构体sa_family_t    sin_family;//2B AF_INET(IPV4)in_port_t      sin_port;  //2B 端口号struct in_addr sin_addr;  //4B IP地址unsigned char sin_zero[8]; //无实际意义 只是为了跟sockaddr大小对齐
}
struct in_addr{	//Internet地址---32位网络字节序uint32_t s_addr;
}   

IP地址转换补充:

#include <arpa/inet.h>//将点分十进制形式IP地址的字符串 转换为32位网络字节序整数
//仅用于IPV4,出错时返回-1,因此不能转换全网广播255.255.255.255的地址
in_addr_t inet_addr(const char *cp) #include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>//将点分十进制形式IP地址的字符串 转换为32位网络字节序整数
//IPV4和IPV6都可用,能正确处理全网广播的地址
int inet_pton(int af, const char *src, void *dst)params: af----AF_INET或AF_INET6src---源地址---点分十进制形式IP字符串dst---转换结果地址---32位整数return: 成功返回1 出错返回其他值//和它反过来的,将32位整数转换为点分十进制形式IP地址字符串
//成功返回非空指针,失败返回NULL
const char *inet_ntop(int af, const void * src, char * dst, socklen_t size)   

示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1"
#define BUFSIZE   (128)int main(void)
{int sock_fd;struct sockaddr_in sin;//1.创建if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1 ){perror("socket");exit(1);}//2.绑定 需要先配置sockaddr_inbzero(&sin,sizeof(sin));//清零再填充 sin.sin_family = AF_INET;//IPV4sin.sin_port   = htons(SERV_PORT);//端口号转换网络字节序//两种IP地址转换//sin.sin_addr.s_addr = inet_addr(SERV_IP);if( inet_pton(AF_INET,SERV_IP,(void*)&sin.sin_addr) != 1 ) {perror("inet_pton");exit(1);}if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind");exit(1);}

三、监听套接字

#include <sys/types.h>
#include <sys/socket.h>//监听套接字,server端将主动套接字--->被动套接字
int listen(int sockfd, int backlog)params: backlog 一般填5 指同时允许几路客户端和服务器进行正在连接(正在三次握手)ARM最大为8return:成功返回0,出错返回-1 

内核中服务器的套接字fd会维护2个链表:

  • 正在三次握手的客户端链表(数量=2*backlog+1)

  • 已经建立好连接的客户端链表(已完成三次握手且分配好了newfd)

四、等待套接字

#include <sys/types.h>
#include <sys/socket.h>//阻塞等待客户端连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)params: addr 	客户端信息的指针(用户传入,连接完成内核保存进去),不需要的话填NULLaddrlen 客户端信息长度的指针,不需要的话填NULLreturn: 成功返回已建立连接的新的客户端描述符newfd(非负整数)出错返回-1

五、服务器端示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1"
#define BUFSIZE   (128)
#define QUIT_STR  "quit"int main(void)
{int sock_fd,newfd;struct sockaddr_in sin;char rd_buf[BUFSIZE];int read_num;//1.创建if( (sock_fd = socket(AF_INET,SOCK_STREAM,0)) == -1 ){perror("socket");exit(1);}//2.绑定 需要先配置sockaddr_inbzero(&sin,sizeof(sin));//清零再填充 sin.sin_family = AF_INET;//IPV4sin.sin_port   = htons(SERV_PORT);//端口号转换网络字节序//两种IP地址转换//sin.sin_addr.s_addr = inet_addr(SERV_IP);if( inet_pton(AF_INET,SERV_IP,(void*)&sin.sin_addr) != 1 ) {perror("inet_pton");exit(1);}if(bind(sock_fd,(struct sockaddr*)&sin,sizeof(sin)) == -1){perror("bind");exit(1);}//3.监听if( listen(sock_fd,5) == -1 ){perror("listen");exit(1);}//4.阻塞等待客户端连接 连接成功后需要newfdif( (newfd = accept(sock_fd,NULL,NULL)) == -1 ){perror("accept");exit(1);}while(1){bzero(rd_buf,BUFSIZE); //读之前先请零do{read_num = read(newfd,rd_buf,BUFSIZE-1);}while(read_num < 0 && errno == EINTR);if(read_num < 0){perror("read");}if(read_num == 0) //客户端关闭{printf("Client is closed!\n");break;}printf("Server received:%s\n",rd_buf);if( strncasecmp(rd_buf,QUIT_STR,strlen(rd_buf)) == 0)//客户端输入quit{printf("Client is exiting!\n");break;}}close(newfd);.	close(sock_fd);return 0;
}

六、连接套接字

#include <sys/types.h>
#include <sys/socket.h>//连接服务器创建的套接字----客户端用
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)params: //参数同bind----表示配置方式相近   return: 成功返回0,出错返回-1

七、客户端示例

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h> //exit
#include <string.h> //bzero
#include <strings.h> //strncasecmp 忽略大小写比较
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define SERV_PORT (5001)
#define SERV_IP   "127.0.0.1" //只能用ifconfig查到的
#define BUFSIZE   (128)
#define QUIT_STR  "quit"int main(void)
{int sock_fd;struct sockaddr_in cin;char wr_buf[BUFSIZE];//1.创建sock_fd = socket(AF_INET,SOCK_STREAM,0);if(sock_fd == -1){perror("socket");exit(1);}//2.连接服务器,还是一样先配置sockaddr_inbzero(&cin,sizeof(cin));cin.sin_family = AF_INET;cin.sin_port   = htons(SERV_PORT);//cin.cin_addr.s_addr = inet_addr(SERV_IP); if( inet_pton(AF_INET,SERV_IP,(void*)&cin.sin_addr) != 1 ){perror("inet_pton");exit(1);}if( connect(sock_fd,(struct sockaddr*)&cin,sizeof(cin)) == -1 ){perror("connect");exit(1);}//3.写数据while(1){bzero(wr_buf,BUFSIZE);//写之前先清零if( fgets(wr_buf,BUFSIZE-1,stdin) == NULL){continue;//重新获取}write(sock_fd,wr_buf,strlen(wr_buf));//写数据--相当于发送给服务器if( strncasecmp(wr_buf,QUIT_STR,strlen(QUIT_STR)) == 0) //输入了quit{break;} }close(sock_fd);return 0;
}

八、Send和Recv

1.网络发送数据

#include <sys/types.h>
#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags)params: 前三个参数同writeflags	一般填0---此时同writeMSG_DONTWAIT 非阻塞版本MSG_OOB 用于发送TCP类型的带外数据(out-of-band)

2.网络接收数据

#include <sys/types.h>
#include <sys/socket.h>ssize_t read(int sockfd, const void *buf, size_t len, int flags)params: 前三个参数同readflags	一般填0---此时同readMSG_DONTWAIT 非阻塞版本MSG_OOB 用于发送TCP类型的带外数据(out-of-band)MSG_PEEK 偷看数据,读完不清除,非常实用return: 成功返回收到字节数,失败返回-1

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com