一.socket编程函数
1.socket函数
原型:int socket(int domain, int type, int protocol);
作用: 创建一个端点并返回一个socket描述符。
参数解析:
domain: 指定一个会话域名,选择一个协议族用于这个会话。包含于<sys/socket.h>中。目前默认格式包括
AF_UNIX,AF_LOCAL AF_INET AF_INET6...
type: 新套接口的类型描述。
SOCK_STREAM SOCK_DGRAM SOCK_SEQQPACKET...
protocol: 通过domain和type已经基本确定了新建的socket具体是什么类型的套接字,最后一步通过protocol来确定socket到底支持的哪个协议(TCP?UDP?)。
为0,则可以理解为一个通配符也可以理解为一个默认值,就是说我不指定protocol,由内核自己决定使用哪一个protocol。
返回值:成功返回socket描述,失败返回-1.
2.bind函数
原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
作用:当通过socket创建一个描述符后,它就存在一个名字空间,但未给它分配地址空间。bind函数就是将addr地址分配给sockfd.
参数解析:
sockfd:未分配地址空间的socket描述符。
addr:地址指针。
赋值:
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_nPort);
addr.sin_addr.s_addr = INADDR_ANY;
INADDR_ANY:表示当主机有多个ip时,客户连接任意ip都可以。
addrlen:地址长度。
返回值:成功返回0,失败返回-1.
3.listen函数
原型:int listen(int sockfd, int backlog);
作用:处理客户端三次握手过程。
参数解析:
sockfd:分配地址空间的socket描述符。
backlog:backlog参数决定了未完成队列和已完成队列中连接数目之和的最大值。
内核为任何一个给定的监听套接字维护两个队列。
1)未完成连接队列
由客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手的过程。
这些套接字处于SYN_RCVD状态。
2)已完成连接队列
每个已完成TCP三路握手过程的客户对应其中一项。这些套接字处于ESTABLISHED状态。
返回值:成功返回0,失败返回-1.
4.accept函数
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
作用:从bind的已完成连接队列中获取一个fd及地址信息。如果该队列为空,则进程进入休眠(套接字为阻塞方式)。
参数解析:
sockfd:分配地址空间的socket描述符。
addr:保存接收到客户的地址信息。
addrlen:客户地址长度。
返回值:成功返回客户连接socket描述符,失败返回-1。
listen和accept过程参考文档:
http://blog.csdn.net/ordeder/article/details/21551567
5.connect函数
原型:int connet(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
作用:用于TCP客户来与服务器建立连接。
客户端调用connect前并不需要非得调用bind函数,因为内核会根据源IP地址,选择一个临时端口作为源端口。
如果是TCP套接字,调用connect函数将会激发TCP的三路握手过程,而且仅在连接建立成功或出错时才返回。
参数解析:
sockfd:分配地址空间的socket描述符。
servaddr:指向套接字地址结构的指针,包含服务器IP和端口号。
addrlen:套接字地址结构大小。
返回值:成功返回0,错误返回-1.若失败,需要重新创建套接字。
6.recv函数
原型:ssize_t recv(int sockfd, void *buf, size_t len, int flags);
作用:将sockfd接收缓冲区的内容copy到buf中。
recv函数仅仅是copy数据,真正的接收数据是协议来完成的
参数解析:
sockfd:分配地址空间的socket描述符。
buf:保存接收数据。
len:从sockfd内核接收缓冲区中copy数据长度。
flags:一般填0,设置模式。
返回值:大于0表示接收数据字节长度,0表示对方断开连接,-1表示失败。
7.send函数
原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags);
作用:将buf中的内容copy到sockfd内核发送缓冲区中。
send函数仅仅是copy数据,真正的发送数据是协议来完成的
参数解析:
sockfd:分配地址空间的socket描述符。
buf:保存发送数据。
len:将buf数据copy到sockfd内核发送缓冲区中的长度。
flags:一般填0,设置模式。
返回值:返回发送的字节长度。-1表示失败。
send和recv函数处理过程参考文档:
http://www.cnblogs.com/jianqiang2010/archive/2010/08/20/1804598.html
8.setsockopt函数
9.getsockopt函数
10.其他函数
inet_pton, inet_ntop, getsockname, getpeername
二.问题
1.socket阻塞和非阻塞的区别(列全)
阻塞:当发出一个不能立即完成的套接字调用时,其进程进入休眠状态,等待相应操作完成。
socket阻塞分为以下4类:
1)输入操作:read、readv、recv、recvfrom、recvmsg
对于阻塞的TCP套接字,如果套接字的接收缓冲区中没有数据可读,该进程将被投入休眠,直到有数据到达。
对于非阻塞套接字,如果接收缓冲区中没有数据可读,相应的调用将立即返回一个EWOULDBLOCK错误。
2)输出操作:write、writev、send、sendto、sendmsg
内核将从应用进程的缓冲区copy到该套接字的发送缓冲区。
对于阻塞套接字,如果其套接字发送缓冲区中没有空间,进程将被投入睡眠,直到有空间为止。
对于非阻塞的TCP套接字,如果其发送缓冲区中根本没有空间,输出函数调用将立即返回一个EWOULDBLOCK错误。如果有发送缓冲区中有一些空间,
返回值将是内核能够复制到该缓冲区中的字节数。
3)接收外来连接:accept
对于阻塞套接字调用accept函数,当无新连接到达,调用进程将被投入休眠。
对于非阻塞套接字调用accept函数,当无新连接到达,accept调用将立即返回一个EWOULDBLOCK错误。
4)发起外出连接:connect
对于阻塞套接字,连接不上则阻塞(Linux阻塞75s),如果想不阻塞,则可以采用定时器信号的机制处理。
对非阻塞套接字,连接不上则立即返回,若为0,则表示已经建立连接;若为-1,如果error为EINPROGRESS,则使用select函数监测fd的连接状态。
fcntl函数设置。
参考文档:
http://blog.csdn.net/pingnanlee/article/details/7770087
http://blog.csdn.net/nphyez/article/details/10268723
2.gdb调试coredump文件时,函数名为????问号
一些库找不到(/lib/libstdc++.so.6),或者版本不匹配。
3.sleep和阻塞等待的区别
4.epoll模型详细处理过程
5.nginx详解
6.三次握手与四次挥手的过程。
三次握手:
1)客户端发送SYN包到服务器,并进入SYN_SEND状态,等待服务器确认。
2)服务器收到SYN包,并确认。同时自己发送一个SYN包,及ACK+SYN,服务器进入SYN_RECV状态。
3)客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
四次挥手:
TCP是全双工通信方式。
1)发起关闭一端发出FIN,告诉被关闭端,我关闭发送链路,不再发送数据给你,但你可以发送数据给我。
2)被动关闭一端发出ACK,确认。
3)被动关闭一端发出FIN,告诉关闭端,我关闭我的发送链路,不再发送数据给你。
4)发起关闭一端发出ACK。
7.TIME_WAIT与CLOSE_WAIT状态
CLOSE_WAIT:
在关闭TCP连接时,
发起TCP连接关闭的一方称为client,被动关闭的一方称为server。被动关闭的server收到FIN后,但未发出ACK的TCP状态是CLOSE_WAIT。
TIME_WAIT:
根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态。
TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。
TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,
如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket,
甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。
可以通过设置端口复用或修改TIME_WAIT等待时间的方式,解决TIME_WAIT状态的问题。
参考文档:
http://www.cnblogs.com/sunxucool/p/3449068.html
http://www.cnblogs.com/Jessy/p/3535612.html
8.TIME_WAIT状态设置的意义
9.SO_REUSEADDR如何解决TIME_WAIT状态下端口复用的问题?
设置了SO_REUSEADDR这个标志的socket,在bind端口时,如果这个端口没在使用或者在使用但处于TIME_WAIT状态,可以绑定成功。
如果正在使用处于非TIME_WAIT状态,则绑定失败。
参考文档:
http://www.cnblogs.com/qq78292959/archive/2013/01/18/2865926.html
9.TCP/IP如何保证数据的准确性和顺序性
10.线程同步(Linux)
1)互斥锁
2)信号量
3)条件变量
11.进程间通信
socket错误编码表:
http://blog.chinaunix.net/uid-116213-id-3376727.html
网络编程:
http://blog.csdn.net/weiyuefei/article/category/2821641
http://blog.csdn.net/weiyuefei/article/details/52242778
复习板块:
1.C/C++基本语法
2.TCP/IP协议
3.socket编程
4.线程和进程同步与异步以及如何编程
5.服务器并发处理(epoll)
6.使用了哪些开源库
jsoncpp, tinyxml, openssl, mongodb
1.socket函数
原型:int socket(int domain, int type, int protocol);
作用: 创建一个端点并返回一个socket描述符。
参数解析:
domain: 指定一个会话域名,选择一个协议族用于这个会话。包含于<sys/socket.h>中。目前默认格式包括
AF_UNIX,AF_LOCAL AF_INET AF_INET6...
type: 新套接口的类型描述。
SOCK_STREAM SOCK_DGRAM SOCK_SEQQPACKET...
protocol: 通过domain和type已经基本确定了新建的socket具体是什么类型的套接字,最后一步通过protocol来确定socket到底支持的哪个协议(TCP?UDP?)。
为0,则可以理解为一个通配符也可以理解为一个默认值,就是说我不指定protocol,由内核自己决定使用哪一个protocol。
返回值:成功返回socket描述,失败返回-1.
2.bind函数
原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
作用:当通过socket创建一个描述符后,它就存在一个名字空间,但未给它分配地址空间。bind函数就是将addr地址分配给sockfd.
参数解析:
sockfd:未分配地址空间的socket描述符。
addr:地址指针。
赋值:
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_nPort);
addr.sin_addr.s_addr = INADDR_ANY;
INADDR_ANY:表示当主机有多个ip时,客户连接任意ip都可以。
addrlen:地址长度。
返回值:成功返回0,失败返回-1.
3.listen函数
原型:int listen(int sockfd, int backlog);
作用:处理客户端三次握手过程。
参数解析:
sockfd:分配地址空间的socket描述符。
backlog:backlog参数决定了未完成队列和已完成队列中连接数目之和的最大值。
内核为任何一个给定的监听套接字维护两个队列。
1)未完成连接队列
由客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手的过程。
这些套接字处于SYN_RCVD状态。
2)已完成连接队列
每个已完成TCP三路握手过程的客户对应其中一项。这些套接字处于ESTABLISHED状态。
返回值:成功返回0,失败返回-1.
4.accept函数
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
作用:从bind的已完成连接队列中获取一个fd及地址信息。如果该队列为空,则进程进入休眠(套接字为阻塞方式)。
参数解析:
sockfd:分配地址空间的socket描述符。
addr:保存接收到客户的地址信息。
addrlen:客户地址长度。
返回值:成功返回客户连接socket描述符,失败返回-1。
listen和accept过程参考文档:
http://blog.csdn.net/ordeder/article/details/21551567
5.connect函数
原型:int connet(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
作用:用于TCP客户来与服务器建立连接。
客户端调用connect前并不需要非得调用bind函数,因为内核会根据源IP地址,选择一个临时端口作为源端口。
如果是TCP套接字,调用connect函数将会激发TCP的三路握手过程,而且仅在连接建立成功或出错时才返回。
参数解析:
sockfd:分配地址空间的socket描述符。
servaddr:指向套接字地址结构的指针,包含服务器IP和端口号。
addrlen:套接字地址结构大小。
返回值:成功返回0,错误返回-1.若失败,需要重新创建套接字。
6.recv函数
原型:ssize_t recv(int sockfd, void *buf, size_t len, int flags);
作用:将sockfd接收缓冲区的内容copy到buf中。
recv函数仅仅是copy数据,真正的接收数据是协议来完成的
参数解析:
sockfd:分配地址空间的socket描述符。
buf:保存接收数据。
len:从sockfd内核接收缓冲区中copy数据长度。
flags:一般填0,设置模式。
返回值:大于0表示接收数据字节长度,0表示对方断开连接,-1表示失败。
7.send函数
原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags);
作用:将buf中的内容copy到sockfd内核发送缓冲区中。
send函数仅仅是copy数据,真正的发送数据是协议来完成的
参数解析:
sockfd:分配地址空间的socket描述符。
buf:保存发送数据。
len:将buf数据copy到sockfd内核发送缓冲区中的长度。
flags:一般填0,设置模式。
返回值:返回发送的字节长度。-1表示失败。
send和recv函数处理过程参考文档:
http://www.cnblogs.com/jianqiang2010/archive/2010/08/20/1804598.html
8.setsockopt函数
9.getsockopt函数
10.其他函数
inet_pton, inet_ntop, getsockname, getpeername
二.问题
1.socket阻塞和非阻塞的区别(列全)
阻塞:当发出一个不能立即完成的套接字调用时,其进程进入休眠状态,等待相应操作完成。
socket阻塞分为以下4类:
1)输入操作:read、readv、recv、recvfrom、recvmsg
对于阻塞的TCP套接字,如果套接字的接收缓冲区中没有数据可读,该进程将被投入休眠,直到有数据到达。
对于非阻塞套接字,如果接收缓冲区中没有数据可读,相应的调用将立即返回一个EWOULDBLOCK错误。
2)输出操作:write、writev、send、sendto、sendmsg
内核将从应用进程的缓冲区copy到该套接字的发送缓冲区。
对于阻塞套接字,如果其套接字发送缓冲区中没有空间,进程将被投入睡眠,直到有空间为止。
对于非阻塞的TCP套接字,如果其发送缓冲区中根本没有空间,输出函数调用将立即返回一个EWOULDBLOCK错误。如果有发送缓冲区中有一些空间,
返回值将是内核能够复制到该缓冲区中的字节数。
3)接收外来连接:accept
对于阻塞套接字调用accept函数,当无新连接到达,调用进程将被投入休眠。
对于非阻塞套接字调用accept函数,当无新连接到达,accept调用将立即返回一个EWOULDBLOCK错误。
4)发起外出连接:connect
对于阻塞套接字,连接不上则阻塞(Linux阻塞75s),如果想不阻塞,则可以采用定时器信号的机制处理。
对非阻塞套接字,连接不上则立即返回,若为0,则表示已经建立连接;若为-1,如果error为EINPROGRESS,则使用select函数监测fd的连接状态。
fcntl函数设置。
参考文档:
http://blog.csdn.net/pingnanlee/article/details/7770087
http://blog.csdn.net/nphyez/article/details/10268723
2.gdb调试coredump文件时,函数名为????问号
一些库找不到(/lib/libstdc++.so.6),或者版本不匹配。
3.sleep和阻塞等待的区别
4.epoll模型详细处理过程
5.nginx详解
6.三次握手与四次挥手的过程。
三次握手:
1)客户端发送SYN包到服务器,并进入SYN_SEND状态,等待服务器确认。
2)服务器收到SYN包,并确认。同时自己发送一个SYN包,及ACK+SYN,服务器进入SYN_RECV状态。
3)客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。
四次挥手:
TCP是全双工通信方式。
1)发起关闭一端发出FIN,告诉被关闭端,我关闭发送链路,不再发送数据给你,但你可以发送数据给我。
2)被动关闭一端发出ACK,确认。
3)被动关闭一端发出FIN,告诉关闭端,我关闭我的发送链路,不再发送数据给你。
4)发起关闭一端发出ACK。
7.TIME_WAIT与CLOSE_WAIT状态
CLOSE_WAIT:
在关闭TCP连接时,
发起TCP连接关闭的一方称为client,被动关闭的一方称为server。被动关闭的server收到FIN后,但未发出ACK的TCP状态是CLOSE_WAIT。
TIME_WAIT:
根据TCP协议定义的3次握手断开连接规定,发起socket主动关闭的一方 socket将进入TIME_WAIT状态。
TIME_WAIT状态将持续2个MSL(Max Segment Lifetime),在Windows下默认为4分钟,即240秒。
TIME_WAIT状态下的socket不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,
如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT状态的socket,
甚至比处于Established状态下的socket多的多,严重影响服务器的处理能力,甚至耗尽可用的socket,停止服务。
可以通过设置端口复用或修改TIME_WAIT等待时间的方式,解决TIME_WAIT状态的问题。
参考文档:
http://www.cnblogs.com/sunxucool/p/3449068.html
http://www.cnblogs.com/Jessy/p/3535612.html
8.TIME_WAIT状态设置的意义
9.SO_REUSEADDR如何解决TIME_WAIT状态下端口复用的问题?
设置了SO_REUSEADDR这个标志的socket,在bind端口时,如果这个端口没在使用或者在使用但处于TIME_WAIT状态,可以绑定成功。
如果正在使用处于非TIME_WAIT状态,则绑定失败。
参考文档:
http://www.cnblogs.com/qq78292959/archive/2013/01/18/2865926.html
9.TCP/IP如何保证数据的准确性和顺序性
10.线程同步(Linux)
1)互斥锁
2)信号量
3)条件变量
11.进程间通信
socket错误编码表:
http://blog.chinaunix.net/uid-116213-id-3376727.html
网络编程:
http://blog.csdn.net/weiyuefei/article/category/2821641
http://blog.csdn.net/weiyuefei/article/details/52242778
复习板块:
1.C/C++基本语法
2.TCP/IP协议
3.socket编程
4.线程和进程同步与异步以及如何编程
5.服务器并发处理(epoll)
6.使用了哪些开源库
jsoncpp, tinyxml, openssl, mongodb