1.套接字
int socket(int domain, int type, int protocol);
domain:AF_INET--->IPV4, AF_INET6---->IPV6
type:SOCK_STREAM--->TCP, SOCK_DGRAM--->UDP, SOCK_RAW--->ICMP
protocol:0
返回一个套接字描述符
2.
通信进程的区分用端口号。
在服务端将端口号和ip地址绑定,为客户端连接做准备。
int bind(int sockfd, struct sockaddr *saddr, int addrlen);
参数:
struct sockaddr
{
unsigned short sa_family;
char sa_data[14];
};
struct sockaddr_in
{
short int sa_family; //地址族
unsigned short int sin_port; //端口号
struct in_addr sin_addr; //ip地址
unsigned char sin_zero[8]; //
char sa_data[14];
};
struct in_addr
{
unsigned long int s_addr; //ip地址
};
常用结构sockaddr_in。
端口字节序转换:
uint16_t htons(uint16_t host16bit);
uint32_t htonl(uint32_t host16bit);
uint16_t ntohs(uint16_t net16bit);
uint32_t ntohs(uint16_t net16bit);
字符串ip地址与网络字节序的二进制数值ip转换:
int inet_aton(const char *straddr, struct in_addr *addrptr); //字符串格式的ip转换为网络地址,保存到addrptr中
char *inet_ntoa(struct in_addr inaddr);
in_addr_t inet_addr(const char *straddr);
对于ipv6可以使用下面函数:
int inet_pton(int family, const char *src, void *dst);
const char * inet_ntop(int family, const char *src, void *dst, socklen_t len);
3.监听:
与客户端的connect函数实现连接。即三次握手过程。
int listen(int sockfd, int backlog);
backlog:最大的连接数
4.accept.从连接队列中读取一个连接,返回新的套接字,使用这个套接字与客户端通信,将客户端的主机地址及端口保存于参数addr中。
int accept(int s, struct sockaddr *addr, int *addrlen);
5.读取数据
int recv(int sockfd, void *buf, int len, unsigned int flags);
从接收缓冲区读出数据
6.send:
int send(int sockfd, const void *buf, int len, unsigned int flags);
将数据复制到发送缓冲区,复制完成后返回。
7
int close(int fd);
释放文件所占用的资源。
8.
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
客户端使用套接字sockfd连接到serv_addr指定服务器的ip和端口。
9.设置文件为非阻塞
sockfd = socket(AF_INET, SOCK_STREAM, 0);
iflags=fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK | iflags);
10.多路选择
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *excpetfds, struct timeval *timeout );
nfds:最大的描述符+1;
描述符集合的操作:
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set)
void FD_ZERO( fd_set *set)
timewait:
NULL:表示阻塞,
时间设为0:表示不阻塞,直接返回。
时间设为>0:表示设定时间后不管怎样都返回;
struct timeval
{
int tv_sec;
int tv_usec;
};
与少数几个个用户即时通信,可以采用多线程。
当用户数量增大时,可以采用select函数。将与用户连接的套接字添加到集合中,用select监视集合内描述符。
11.域名转换
struct hostent gethostbyname(const char *name);
struct hostent
{
char *h_name; //主机域名
char **h_aliases; //主机别名,以NULL结尾
int h_addrtype; //地址类型
int h_length; //地址字节长度
char **h_addr_list; //包含主机的地址,
};
12
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
sockfd:套接字
level:层次
optname:选项名
optval:选项值
optlen:选项长度
设置缓冲区大小为sendBuf:
setsockopt(sfd, SO_SOCKET, SO_SNDBUF, (const char *)&sendBuf, sizeof(int));
阅读(798) | 评论(0) | 转发(0) |