Linux下Socket编程实现长连接 (socket linux 长连接)

一、长连接概述

长连接是一种客户端与服务器端之间保持连接的方式,即使客户端不发送请求,服务器端仍然保持连接并等待客户端的请求。在客户端和服务器端之间频繁地建立和断开连接的情况下,长连接显得尤为重要。因为建立和断开连接会增加很多开销,而长连接能够减少这种开销。

二、Socket编程

Socket编程是利用基于TCP/IP协议的套接字(socket)来开发网络通信程序的一种方法。Socket可以理解为一种通信桥梁,允许不同的进程通过网络互相通信。Socket编程支持良好,且可以应用于多种操作系统,如Unix、Linux、Windows等。

在Socket编程中,客户端和服务器端之间通常会建立TCP连接。TCP是一种可靠的连接,保证了数据的有序传输和完整性。连接双方可以长时间保持连接,以便使数据传输更加迅速、更加可靠。

三、实现长连接

在进行Socket编程时,可以通过一些手段来实现长连接:

1. 客户端定时发送心跳包

当客户端和服务器端之间缺乏交互时,客户端可以定时向服务器端发送心跳包。一般来说,心跳包是一条无实际意义的消息,其目的是为了让服务器端知道客户端仍然处于活动状态。如果服务器端在一定时间内没有收到心跳包,就可判定客户端已经断开连接。

2. 服务器端定时向客户端发送消息

当服务器端有数据需要发送时,可以优先发送给处于长连接状态的客户端。此时,服务器端可以利用发送数据的机会,向客户端发送一条带有心跳信息的数据。在此过程中,服务器端可以做出判断,如果客户端在规定时间内没有回复心跳信息,就可以认为客户端已经与服务器端断开连接。

3. 利用Socket选项设置

Socket的选项设置可以控制Socket的运行模式和特性。Options如SO_KEEPALIVE和TCP_KEEPIDLE可以让Socket保持连接状态,提高数据传输效率。SO_KEEPALIVE选项设置从发送方向接收心跳包,检测连接是否还是活跃的,但是SO_KEEPALIVE并不能保证即时检测的到断开而TCP_KEEPIDLE可以解决这个问题,通过设置TCP_KEEPALIVE选项,可以让Socket在定义的一段时间内没有数据交互就定期地向对端发送心跳包。

四、代码实现

以下是客户端和服务器端基于C++的长连接代码实现:

客户端:

“`cpp

#include

#include

#include

#include

#include

#include

#define MAXLINE 4096

int mn(int argc, char **argv) {

if (argc != 2) {

std::cout ”

return -1;

}

int sockfd;

struct sockaddr_in servaddr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd

std::cout

return -1;

}

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(9999);

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr)

std::cout

return -1;

}

if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))

std::cout

return -1;

}

char sendBuff[MAXLINE], recvBuff[MAXLINE];

int n;

while (true) {

bzero(sendBuff, sizeof(sendBuff));

bzero(recvBuff, sizeof(recvBuff));

sprintf(sendBuff, “hello world\n”);

write(sockfd, sendBuff, strlen(sendBuff));

if ((n = read(sockfd, recvBuff, MAXLINE)) > 0) {

recvBuff[n] = 0;

std::cout

}

}

shutdown(sockfd, SHUT_RDWR);

return 0;

}

“`

服务器端:

“`cpp

#include

#include

#include

#include

#include

#include

#include

#define MAXLINE 4096

#define LISTENQ 5

int mn() {

int listenfd, connfd;

struct sockaddr_in servaddr;

char buff[MAXLINE];

listenfd = socket(AF_INET, SOCK_STREAM, 0);

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(9999);

bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

listen(listenfd, LISTENQ);

std::cout

for (;;) {

connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);

FILE *fp = fdopen(connfd, “r+”);

setvbuf(fp, NULL, _IONBF, 0);

while (fgets(buff, MAXLINE, fp) != NULL) {

printf(“recv: %s”, buff);

fflush(stdout);

}

fclose(fp);

close(connfd);

}

return 0;

}

“`

上面的代码实现了一个简单的长连接,其中客户端发送一条消息后等待服务器端的响应,如果服务器端没有响应,客户端就会一直等待。

五、

长连接可以有效地减少网络通信的开销,提高数据传输效率和稳定性。而Socket编程是实现长连接的一种通用方式,支持多种操作系统和开发语言。

在实现长连接时,Socket的选项设置可以提高Socket的运行效率,客户端可以定时发送心跳包,服务器端也可以定时向客户端发送消息,以此来保持长连接的状态。

相关问题拓展阅读:

Socket,http长连接与短连接

在网络层有IP协议,ICMP协议,ARP协议,RARP协议和BOOTP协议.

在传输层中有:TCP协议与UDP协议.

在应用层有:通过TCP协议来通信的应用层协议包括FTP,HTTP,TELNET,TP协议. 通过UDP协议来通信的应用层春派协议包括DNS,TFTP等;

连接->数据传输->关闭连接

HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,单任务结束后就返森帆中断连接.也可以这样说:短连接是指Socket连接后发送后接收完数据后马上断开连接.

连接->传输数据->保持连接->传输数据->….->关闭连接

长连接指建立socket连接后不管是否使用都保持连接,但安全性较差.

http的长连接

HTTP也可以建立长连接的,使用Connection:keep-alive,HTTP1.1默认进行持久连接,HTTP1.1和HTTP1.0相比较而言更大的区别就是添加了持久连接支持(貌似最新的http1.0可以显示的指定keep-alive)但还是无状态的,或者说是不可信任的.

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况.每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接在操作的话那么处理时间会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用再次建立连接.例如即使通讯环信底层用的就是长连接聊天过程中为了保证消息的实时性,保持长连接进行会话!

而web网站的http服务一般用短连接,因为长连接对于服务端来说会耗费一定的资源,而像web网站这样频繁成千上万甚至上亿客户端的连接用短连接会更省资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,并发数会很大,这样后台服务器有承受很大的压力,所以这种情况小用短连接会比较好.

Socket是应用层与TCP/IP协议通讯的中间软件抽象层,它是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的TCP/IP组协议隐藏在了socket接口后面,对用户来说简单的接口就是全部,让socket去组织数据,以符合指定的协议.

主机A的应用程序要和主机B的应用程序进行通信,必须通过socket建立连接,而建立socket连接必须通过底层的TCP/IP协议建立TCP连接,建立TCP连接需要底层IP协议来寻址网络中的主机.我们知道网络中的IP协议可以帮助我们根据IP地址来找到目标主机但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过TCP和UDP的地址也就是端口号来指定,这样就可以通过socket实例唯一代表一个主机上的一个应用程序的通信链路了.

(1)之一次握手:Client(客户端)将标识位SYN(发起一个新连接)置为1,随机产生一个(序号:发送数据对其标识)seq=J,并将该数据发送给server(服务器),Client(客漏雹户端)进入SYN_SENT状态,等待Server确认.

(2)第二次握手:Server收到数据包后由SYN=1知道Client请求建立连接,Server将SYN和ACK都置为1,ack=J+1;.随机产生一个seq=k,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态.

(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标识位ACK置为1,ack=k+1;并将数据包发送给Server,Sever检查ack是否为k+1,ACK是否为1,如果正确则建立连接Client和server进入ESTABLISHED状态,完成三次握手,随后Client和Server之间可以开始传输数据了.

(1)之一次挥手:Client发送一个FIN(释放一个连接),用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK(确认序号有效)状态.

(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

Q1 : HTTP Socket TCP UDP都是什么?

HTTP 全称是超文本传输协议,是一个应用层的协议。用于客户端和服务端之间进行通讯。

TCP/UDP 都是传输层协议。TCP是可靠的,我们常说的三次握手连接,四次握手断开都是说的TCP。而UDP是不可靠的。

Socket 则是从传输层抽象出来的接口层。

Q2 : HTTP连接和Socket连接有什么区别?分别在什么情况下使用?

HTTP 是基于TCP的短连接。需要经过三次握手建立连接,且无法保持始终连接。

Socket 是长连接。基于TCP的Socket连接,一旦建立三次握手,除非一方主动断开,否则连接状态一直保存。也可以基于UDP进行Socket连接。

HTTP连接,服务端无法主动发消息,采用的是’请求-响应’机制。客户端没有发消息给服务端,服务端无法推送消息给客户端。

Socket连接,一方可以随时向另一方发起会话。

双方不需要时刻保持连接在线用HTTP。eg : 客户端资源获取、上传文件等。

即时通讯应用需要用Socket连接。eg : 微信、苹果的APNs等。

Q3 : HTTPS是什么?和HTTP有什么区别?

HTTPS就是HTTP加上SSL/TLS。TLS(Transport Layer Security)传输层安全协议,作用是在传输层对网络连接加密。SSL就是TLS的前身。

HTTP端口是80,是无状态的。HTTPS端口是443,是可以进行加密传输、身份认证的网络协议。

怎么建立socket长连接

非蠢肢要用socket,就socket.setdefaulttimeout和settimeout设置连接时间 while 1接受。长满没坦告法 聊天室一般不用socket保持连接,占用多巨让档明大cpu,一般即时游戏才用。 聊天可以在http协议上构建,做周期轮询就行。python也内置了http客服两端

关于socket linux 长连接的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Linux下Socket编程实现长连接 (socket linux 长连接)