<>套接字( socket )

套接字( socket )也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。

(1)服务器:server
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
将套接字与服务器网络信息结构体绑定 bind( )
将套接字设置为被动监听模式 listen( )
阻塞等待客户端的连接请求 accept( )
进行通信 recv( )/send( ) (read( )/write( ))
#include <stdio.h> //printf #include <arpa/inet.h> //inet_addr htons #include
<sys/types.h> #include <sys/socket.h> //socket bind listen accept connect #
include <netinet/in.h> //sockaddr_in #include <stdlib.h> //exit #include
<unistd.h> //close #include <string.h> #define N 128 #define errlog(errmsg)
do{perror(errmsg);\ printf("%s -- %s -- %d\n", __FILE__, __func__, __LINE__);\
exit(1);\ }while(0) int main(int argc, const char *argv[]) { int sockfd,
acceptfd; struct sockaddr_in serveraddr, clientaddr; socklen_t addrlen = sizeof(
serveraddr); char buf[N] = {}; ssize_t bytes; if(argc < 3) { fprintf(stderr,
"Usage: %s <ip> <port>\n", argv[0]); exit(1); } //第一步:创建套接字 if((sockfd = socket(
AF_INET, SOCK_STREAM, 0)) < 0) { errlog("fail to socket"); } //第二步:填充服务器网络信息结构体
//inet_addr:将点分十进制ip地址转化为网络字节序的整型数据 //htons:将主机字节序转化为网络字节序 //atoi:将数字型字符串转化为整型数据
serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = inet_addr(argv[1]
); serveraddr.sin_port = htons(atoi(argv[2])); //第三步:将套接字与服务器网络信息结构体绑定 if(bind(
sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0) { errlog("fail
to bind"); } //第四步:将套件字设置为被动监听状态 if(listen(sockfd, 5) < 0) { errlog("fail to
listen"); } //第五步:阻塞等待客户端的连接请求 if((acceptfd = accept(sockfd, (struct sockaddr *)
&clientaddr, &addrlen)) < 0) { errlog("fail to accept"); } //服务器知道客户端的信息 printf(
"%s --> %d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
while(1) { if((bytes = recv(acceptfd, buf, N, 0)) < 0) { errlog("fail to recv");
} else if(bytes == 0) { printf("NO DATA\n"); exit(1); } else { if(strncmp(buf,
"quit", 4) == 0) { printf("The client is quited\n"); break; } printf("client:
%s\n", buf); strcat(buf, " *_*"); if(send(acceptfd, buf, N, 0) < 0) { errlog(
"fail to send"); } } } close(acceptfd); close(sockfd); return 0; }
(2)客户端:client
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
发送客户端的连接请求 connect( )
进行通信 send( )/recv( )
#include <stdio.h> //printf #include <arpa/inet.h> //inet_addr htons #include
<sys/types.h> #include <sys/socket.h> //socket bind listen accept connect #
include <netinet/in.h> //sockaddr_in #include <stdlib.h> //exit #include
<unistd.h> //close #include <string.h> #define N 128 #define errlog(errmsg)
do{perror(errmsg);\ printf("%s -- %s -- %d\n", __FILE__, __func__, __LINE__);\
exit(1);\ }while(0) int main(int argc, const char *argv[]) { int sockfd; struct
sockaddr_in serveraddr; socklen_t addrlen = sizeof(serveraddr); char buf[N] = {}
; if(argc < 3) { fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]); exit(1); }
//第一步:创建套接字 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { errlog("fail
to socket"); } //第二步:填充服务器网络信息结构体 //inet_addr:将点分十进制ip地址转化为网络字节序的整型数据
//htons:将主机字节序转化为网络字节序 //atoi:将数字型字符串转化为整型数据 serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]); serveraddr.sin_port = htons(
atoi(argv[2])); #if 0 //客户端可以自己指定信息 struct sockaddr_in clientaddr; clientaddr.
sin_family= AF_INET; clientaddr.sin_addr.s_addr = inet_addr(argv[3]); clientaddr
.sin_port = htons(atoi(argv[4])); if(bind(sockfd, (struct sockaddr *)&clientaddr
, addrlen) < 0) { errlog("fail to bind"); } #endif //第三步:发送客户端的连接请求 if(connect(
sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0) { errlog("fail to connect"
); } while(1) { fgets(buf, N, stdin); buf[strlen(buf) - 1] = '\0'; if(send(
sockfd, buf, N, 0) < 0) { errlog("fail to send"); } if(strncmp(buf, "quit", 4)
== 0) { printf("The client is quited\n"); break; } if(recv(sockfd, buf, N, 0) <
0) { errlog("fail to recv"); } printf("server: %s\n", buf); } close(sockfd);
return 0; }

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信