socket网络编程基础

2017-3-8来源:ASP.NET技巧人气:382

一.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