首页 > 学院 > 开发设计 > 正文

socket网络编程基础

2019-11-06 05:26:51
字体:
来源:转载
供稿:网友
一.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/215515675.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.html8.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/7770087http://blog.csdn.net/nphyez/article/details/102687232.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.htmlhttp://www.cnblogs.com/Jessy/p/3535612.html8.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.html9.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/2821641http://blog.csdn.net/weiyuefei/article/details/52242778复习板块:1.C/C++基本语法2.TCP/IP协议3.socket编程4.线程和进程同步与异步以及如何编程5.服务器并发处理(epoll)6.使用了哪些开源库  jsoncpp, tinyxml, openssl, mongodb
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表