001:
fcntl函数:
可以改变已打开的文件性质,针对(文件)描述符提供控制,点击查看详情
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
参数fd 是被参数cmd操作(如下面的描述)的描述符.针对cmd的值,fcntl能够接受第三个参数int arg
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int flags;
/* 设置为非阻塞*/
if (fcntl(socket_descriptor, F_SETFL, flags | O_NONBLOCK) < 0)
{
/* Handle error */
}
/* 设置为阻塞 */
if ((flags = fcntl(sock_descriptor, F_GETFL, 0)) < 0)
{
/* Handle error */
}
002:
inet_pton函数:
Linux下IP地址转换函数,这个函数转换字符串到网络地址,可以在将IP地址在“点分十进制”和“整数”之间转换,而且,inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。算是比较新的函数了,inet_pton 是inet_addr。点击查看详情
int inet_pton(int af, const char *src, void *dst);
第一个参数af是地址族,第二个参数*src是来源地址,第三个参数* dst接收转换后的数据。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main (void)
{
char IPdotdec[20]; //存放点分十进制IP地址
struct in_addr s; // IPv4地址结构体
// 输入IP地址
printf("Please input IP address: ");
scanf("%s", IPdotdec);
// 转换
inet_pton(AF_INET, IPdotdec, (void *)&s);
printf("inet_pton: 0x%x\n", s.s_addr); // 注意得到的字节序
// 反转换
inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
printf("inet_ntop: %s\n", IPdotdec);
}
003:
in_addr结构体:
用来表示一个32位的IPv4地址。
struct in_addr {
in_addr_t s_addr;
};
in_addr_t 一般为 32位的unsigned int
在linux下:
in_addr结构
typedef struct in_addr{
unsigned long s_addr;
};
在windows下:
typedef struct in_addr{
union{
struct{unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b;
struct{unsigned short s_w1,s_w2;} S_un_w;
unsigned long S_addr;
} S_un;
} IN_ADDR;
其中每8位代表一个IP地址位中的一个数值.
例如192.168.3.144记为0xc0a80390,其中 c0 为192 ,a8 为 168, 03 为 3 , 90 为 144
打印的时候可以调用 inet_ntoa()函数将其转换为char *类型。 点击查看详情
004:
sockaddr_in结构体:
指明地址信息,点击查看详情
(在netinet/in.h中定义):
struct sockaddr_in {
short sin_family; /* Address family 一般来说 AF_INET(地址族)PF_INET(协议族 )*/
unsigned short sin_port; /* Port number (必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字) */
struct in_addr sin_addr; /* Internet address */
unsigned char sin_zero[8]; /* Same size as struct sockaddr 没有实际意义,只是为了跟SOCKADDR结构在内存中对齐 */
};
(在ws2def.h中定义):
struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
}
实例:
服务端:
int main()
{
//创建socket
int sockfd=socket(PF_LOCAL, SOCK_DGRAM, 0);
if(sockfd==-1)
perror("创建socket失败"),exit(-1);
//准备通信地址
struct sockaddr_un addr;
addr.sun_family = PF_UNIX;
strcpy(addr.sun_path,"a.sock");
//绑定
int res = bind(sockfd,
(struct sockaddr*)&addr, sizeof(addr));
if(res==-1)perror("绑定失败"),exit(-1);
printf("绑定成功\n");
//通信(用读写文件方式)
char buf[100] = {};
read(sockfd, buf, sizeof(buf));
printf("收到信息:%s\n", buf);
//关闭socket
close(sockfd);
}
客户端:
int main()
{
int sockfd=socket(PF_LOCAL, SOCK_DGRAM, 0);
if(sockfd==-1)
perror("创建socket失败"),exit(-1);
struct sockaddr_un addr;
addr.sun_family = PF_UNIX;
strcpy(addr.sun_path,"a.sock");
//连接
int res = connect(sockfd,
(struct sockaddr*)&addr, sizeof(addr));
if(res==-1)perror("失败"),exit(-1);
printf("成功\n");
write(sockfd, "Hello, Socket!", 14);
close(sockfd);
}
005:主机字节序与网络字节序的换转:htonl、ntohl、htons、ntohs
CPU最大端最小端模式,以及这四个函数的实现:详情看这里
006:listen()函数:
创建一个套接口并监听申请的连接.
#include <winsock.h>
int PASCAL FAR listen( SOCKET s, int backlog);
S:用于标识一个已捆绑未连接套接口的描述字。
backlog:等待连接队列的最大长度。