套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。
套接字类型
(1)
流式套接字
。它提供了一种可靠的、面向连接的双向数据传输服务,实现了数据无差错、无重复的发送。流式套接字内设流量控制,被传输的数据看作是无记录边界的字节流。在TCP/IP协议簇中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
(2)
数据报套接字
。它提供了一种无连接、不可靠的双向数据传输服务。数据包以独立的形式被发送,并且保留了记录边界,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在TCP/IP协议簇中,使用UDP协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。
(3)
原始套接字
。该套接字允许对较低层协议(如IP或ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。
int sockfd = socket(AF_INET,SOCK_STREAM,0);//套接字创建
if(sockfd == -1){
perror("socket");
return -1;
}
struct sockaddr_in addr = {};//准备端口和ip
addr.sin_family = AF_INET;
addr.sin_port = atoi(argv[1]);//端口
addr.sin_addr.s_addr = inet_addr("192.168.x.xx");
int ret = bind(sockfd,(const struct sockaddr*)&addr,sizeof(addr));//把socket和地址(端口和ip)绑定在一起
if(ret == -1){
perror("bind");
return -1;
}
ret = listen(sockfd,10);//设置等待连接状态
if(ret == -1){
perror("listen");
return -1;
}
```c
struct sockaddr_in caddr = {};//用来接收客户端连接上来的地址
socklen_t len = sizeof(caddr);
//accept 会阻塞 当有客户端连接上来时 该函数返回 得到一个新的 fd 用于和客户端进行交互 每当有客户端连接上来,该函数都会返回
int fd = accept(sockfd,(struct sockaddr*)&caddr,&len);
if(fd == -1){
perror("accept");
return -1;
}
pid_t id = fork();
if(id == -1){
perror("fork");
return -1;
}
if(id == 0){
while(true){
//读写fd
char buf[1024] = {};
ret = read(fd,buf,1024);
if(ret <= 0){
return 0;
}
printf("recv:%s\n",buf);
if(strcmp(buf,"bye")==0){
return 0;
}
}
}
while(true){
char buf[1024] = {};
gets(buf);
write(fd,buf,strlen(buf)+1);
if(strcmp(buf,"bye")==0){
break;
}
}
ret = close(sockfd);
if(ret == -1){
perror("close");
}
return 0;
}
版权声明:本文为weixin_45388041原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。