Chinaunix首页 | 论坛 | 博客
  • 博客访问: 43286
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 330
  • 用 户 组: 普通用户
  • 注册时间: 2015-07-28 17:39
文章分类
文章存档

2015年(31)

我的朋友

分类: C/C++

2015-11-07 12:07:48

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));


阅读(808) | 评论(0) | 转发(0) |
0

上一篇:网络

下一篇:ping

给主人留下些什么吧!~~