写server的一些流程总结
一、向内核申请一个socket
TCP形式
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
UDP形式
sfd = socket(AF_UNIX, SOCK_STREAM, 0);
二、使用bind
网络中的地址包括3个方面:1.地址类型 2.IP地址 3.端口
include <netinet/in.h> struct sockaddr { unsigned short sa_family; // 2 bytes address family, AF_xxx char sa_data[14]; // 14 bytes of protocol address }; // IPv4 AF_INET sockets: struct sockaddr_in { short sin_family; // 2 bytes e.g. AF_INET, AF_INET6 unsigned short sin_port; // 2 bytes e.g. htons(3490) struct in_addr sin_addr; // 4 bytes see struct in_addr, below char sin_zero[8]; // 8 bytes zero this if you want to }; struct in_addr { unsigned long s_addr; // 4 bytes load with inet_pton() };
所以使用bind前要先设置参数:
1.清空的写法:
struct sockaddr_in servaddr = {0}; memset(&servaddr , 0, sizeof(struct sockaddr_un)); bzero(&servaddr, sizeof(struct sockaddr_in));
2.设置初值:
servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); /* 设置sin_addr的方式又有不少 */ servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_addr.s_addr = inet_addr("192.168.0.1");
3.运行bind,会把sockaddr_in强制转换成sockaddr
bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in))
三、listen函数
listen(sock_fd, 1);
第二个参数是:等待连接队列的最大长度
四、accept函数
sock_fd = accept(sock_id, NULL, NULL);
第二个和第三个参数与bind类似,不过是客户端的传过来的信息。
accept会返回一个成功连接的socket描述符
对这个返回的描述符写,就是发送数据了