目录
环境及工具
环境 : Ubuntu
工具 : clion 2023.3.2 TCPUDO调试助手(Microsoft Store Download)
第一步 : 创建socket,获取fd
函数原型 : int socket (int domain, int type, int protocol);
domain : 协议(<AF_INET : ipv4> <AF_INET6 : ipv6>)
type : socket类型(< SOCK_STREAM : TCP> < SOCK_DGRAM : UDP> 有三种,常用是两种)
protocol : 赋值"0",由系统自动选择
函数返回值 : 失败-1,成功时返回fd(非负) , 定义一个整型变量sockfd接收;
第二步 : 初始化sockaddr_in结构体
struct sockaddr_in servaddr;
成员1 : sin_family : 协议族,在socket编程中只能是AF_INET
成员2 : sin_addr.s_addr : ip地址
成员3 : sin_port : 端口号
第三步 : 通信的地址和端口绑定到 socckfd
函数原型 : int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
sockfd : 需要绑定的socket。
addr : 通信的地址和端口,就是上面初始化的sockaddr_in结构体。
addrlen : 传入结构体的大小,用sizeof()函数计算
返回值 : 成功则返回0 ,失败返回-1,错误原因存于 errno(这里不做过多阐述,有兴趣码友可以自己了解) 中。
如果绑定的地址错误,或者端口已被占用,bind 函数一定会报错,否则一般不会返回错误。
在终端窗口输入以下指令:
netstat -anop | grep 端口号 //查看端口号状态
第四步 : 实施监听服务
函数原型 : int listen(int sockfd, int backlog);
sockfd : socket()函数返回的描述符;
backlog : 内核为此套接字维护的最大连接个数
源码如下 :
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
int sockfd= socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof (struct sockaddr_in));
servaddr.sin_family=AF_INET;//协议
servaddr.sin_addr.s_addr= htonl(INADDR_ANY);//INADDR_ANY 表示监听0.0.0.0地址
servaddr.sin_port= htons(9999);//如果端口被占用,修改即可
if(bind(sockfd,(struct sockaddr_in*)&servaddr,sizeof (struct sockaddr_in))==-1)
{ //返回值为-1 表示出错,成功时返回一个非负的数
printf("bind failed : %s\n", strerror(errno));//错误原因存于 errno 中
return -1;
}
listen(sockfd,10);
getchar();//io阻塞 防止进程被杀死 用于测试链接
}