socket实现tcp通信

tcp的接口

tcp的详细细节后面讲解,先来用它的一些接口实现1个简单的通信。下面来看它的一套接口

socket

功能:socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符;应用程序可以像读写文件一样用read/write在网络上收发数据;

函数原型:

  int socket(int domain, int type, int protocol);

参数说明:

  • domain:协议域又称协议家族,协议族决定了socket的地址类型,跟udp的一样,用IPv4还是AF_INET
  • type:套接字类别,有流式套接字和数据报套接字,tcp用的是面向流的传输协议,参数为SOCK_STREAM
  • protocol:协议指定与套接字一起使用的特定协议,指定为0即可

返回值:

成功则返回socket文件描述符,错误返回-1.

socket接口在上一篇的udp中已经有了,这里不做多余的讲解。

bind

服务器程序所监听的网络地址和端口号通常是固定不变的,客户端程序得知服务器程序的地址和端口号后就可以向服务器发起连接; 服务器需要调用bind绑定一个固定的网络地址和端口号.

函数原型:

int bind(int socket, const struct sockaddr *address,socklen_t address_len);

参数说明:

  • socket:需要绑定的socket
  • addr:存放了服务端用于通信的地址和端口。
  • addrlen:表示addr结构体的大小。

返回值:

  • 成功返回0,失败返回-1

前面的这2个接口的使用跟udp是一样的。

listen监听

listen声明sockfd处于监听状态, 并且最多允许有backlog个客户端处于连接等待状态, 如果接收到更多
的连接请求就忽略, 这里设置不会太大(一般是5)。udp完成bind后就可以接收和发送信息了,tcp在这里就跟它不同了。为什么要监听呢?因为服务器要知道从客户端发来了请求。
就像在公司的食堂吃饭一样,我们上面时候去都能吃到饭,因为食堂的打饭人员一看到人来就知道有人来吃饭了。这个打饭人员就是处于监听状态,我们吃饭就是客户端的请求。

函数原型:

int listen(int sockfd, int backlog);

参数说明:

  • sockfd:监听的套接字
  • backlog:最多允许有多个客户端处于连接等待状态

返回值:成功返回0,失败返回-1

accept

服务器需要接收客户端的请求,如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来。
函数原型:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数说明:

  • sockfd:要连接的套接字
  • addr:是一个传出参数,accept()返回时传出客户端的地址和端口号;
  • addrlen:参数是一个传入传出参数(value-result argument), 传入的是调用者提供的, 缓冲区addr的长度以避免缓冲区溢出问题, 传出的是客户端地址结构体的实际长度(有可能没有占满调用者提供的缓冲区)

返回值:(重点理解返回值)

成功返回新的套接字,失败返回-1

在这里插入图片描述

为什么返回1个套接字?

来看个例子:
在这里插入图片描述
这个accept的返回值就是这个服务员,sockfd就是这个拉客的,吃饭的人就是客户端发来的请求。
这个拉客的把人带给服务员后,她有继续出去拉客了。sockfd这个套接字继续拉客也就是继续从底层获取客户端的链接,服务员专门处理链接也就是返回的这个套接字,专门处理和用户沟通。

connect

我们的客户端需要调用connet来连接服务器。
函数原型:

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

参数说明:
connect和bind的参数形式一致, 区别在于bind的参数是自己的地址, 而connect的参数是对方的地址;
connect()成功返回0,出错返回-1

recv

功能接收数据。
函数原型:

 ssize_t recv(int sockfd, void *buf, size_t len, int flags);

参数说明:

  • sockfd:指定接收端套接字描述符
  • buf:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
  • len:指明buf的长度
  • flags:参数一般置0

返回值:
成功则返回读出来的大小,失败返回-1.

send

功能发送信息,函数原型

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

参数说明:

  • sockfd:指定发送端套接字描述符
  • buf:指明一个存放应用程序要发送数据的缓冲区;
  • len:指明实际要发送的数据的字节数;
  • flags:参数一般置0。

单进程版tcp通信

下面来利用上面的接口来写个简单服务器和客户端来实现通信,首先是单进程版的。

服务器

整体逻辑:

  • 首先初始化服务器,初始化服务器包括:先创建套接字,创建好后开始绑定,若绑定失败,则直接退出进程。绑定好后开始监听套接字,监听失败也直接退出。
  • 启动服务器:监听成功后,先接收客户端发来的信息,再给客户端发送echo server服务器。

tcpServer.hpp

  1 #pragma once                                                                                                                        
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<stdlib.h>
  5 #include<cstring>
  6 #include<unistd.h>
  7 #include<sys/types.h>
  8 #include<sys/socket.h>
  9 #include<arpa/inet.h>
 10 #include<netinet/in.h>
 11 #define BACKLOG 5
 12 class tcpServer
 13 {
   
 14   private:
 15     int port;
 16     int lsock;
 17   public:
 18   tcpServer(int _port = 8080)
 19     :port(_port)
 20     ,lsock(-1)
 21   {
   }
 22  void initServer()
 23  {
   
 24     lsock = socket(AF_INET,SOCK_STREAM,0);
 25     struct sockaddr_in local;
 26     local.sin_family = AF_INET;//IPv4
 27     local.sin_port = htons(port);//端口号,主机序列转成网络序列
 28     local.sin_addr.s_addr = INADDR_ANY;//ip地址
 29 
 30     //开始绑定
 31     if(bind(lsock,(struct sockaddr*)&local,sizeof(local)) < 0)
 32     {
   
 33        std::cerr<<"bind error"<<std::endl;
 
  • 81
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 56
    评论
### 回答1: Python可以通过socket模块实现TCP通信。下面是一个简单的例子: 服务端代码: ```python import socket HOST = '127...1' # 服务端IP地址 PORT = 8888 # 服务端端口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 s.bind((HOST, PORT)) # 监听客户端连接 s.listen(1) # 等待客户端连接 conn, addr = s.accept() print('Connected by', addr) # 接收客户端发送的数据 data = conn.recv(1024) print('Received from client:', data.decode()) # 发送数据给客户端 conn.sendall('Hello, client!'.encode()) # 关闭连接 conn.close() s.close() ``` 客户端代码: ```python import socket HOST = '127...1' # 服务端IP地址 PORT = 8888 # 服务端端口号 # 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务端 s.connect((HOST, PORT)) # 发送数据给服务端 s.sendall('Hello, server!'.encode()) # 接收服务端发送的数据 data = s.recv(1024) print('Received from server:', data.decode()) # 关闭连接 s.close() ``` 以上代码实现了一个简单的TCP通信,服务端监听客户端连接,客户端连接服务端并发送数据,服务端接收数据并发送响应给客户端,最后关闭连接。 ### 回答2: Python是一种高级编程语言,可用于实现各种应用程序,包括网络通信。在网络编程,Python内置的socket模块可用于实现基于TCP协议的套接字通信。以下是Python实现socket TCP通信的基本流程和实现步骤。 1. 创建socket对象 在Python,我们可以使用socket.socket方法创建TCP服务器或客户端的套接字。通过指定socket.AF_INET参数和socket.SOCK_STREAM参数,我们可以创建一个基于IP地址和TCP协议socket对象。 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 2. 绑定服务器地址和端口(服务器端) 在服务器端,我们需要使用bind方法将服务器IP地址和端口号绑定到套接字上。服务器套接字通过listen方法等待客户端的连接请求。 server_address = ('localhost', 8888) server_socket.bind(server_address) server_socket.listen(5) 3. 客户端连接服务器(客户端) 在客户端,我们可以使用connect方法连接服务器。connect方法需要指定服务器IP地址和端口号。一旦连接建立,客户端就可以向服务器发送数据,同时接收服务器返回的数据。 server_address = ('localhost', 8888) client_socket.connect(server_address) 4. 接收和发送数据 一旦连接建立,服务器和客户端可以相互发送数据。在服务器端,我们可以使用accept方法接受客户端的连接请求,并使用recv方法接收客户端发送的数据。在客户端,我们可以使用send方法向服务器发送数据,并使用recv方法接收服务器返回的数据。 (服务器端) connection, client_address = server_socket.accept() while True: data = connection.recv(1024) if not data: break connection.sendall(data) connection.close() (客户端) message = 'Hello, server!' client_socket.sendall(message.encode()) data = client_socket.recv(1024) print(data.decode()) 5. 关闭套接字 当通信结束时,我们需要使用close方法关闭套接字。 server_socket.close() client_socket.close() 总之,Python实现socket TCP通信包含创建socket对象,绑定服务器地址和端口,客户端连接服务器,接收和发送数据,以及关闭套接字等基本步骤。在实际应用,我们还需要处理异常情况和编写更加健壮的代码,以确保网络通信的可靠性和稳定性。 ### 回答3: Python实现socket TCP通信,可以通过Python内置的socket模块来完成。socket是一种网络通信协议,可以进行网络数据的传输,同时也对网络连接的管理和控制。 首先,需要引入socket模块,并创建Socket对象。可以使用socket.socket()函数来创建Socket对象,该函数需要传入两个参数,第一个参数指定了要使用协议类型(IPv4或IPv6),第二个参数指定了套接字类型(SOCK_STREAM或SOCK_DGRAM)。 例如,以下代码创建了一个IPv4和TCP协议Socket对象: ``` import socket # 创建Socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ``` 其,AF_INET表示使用IPv4协议,而SOCK_STREAM表示使用TCP协议。 接着,需要绑定Socket对象的IP地址和端口号。可以使用Socket对象的bind()函数来完成。bind()需要传入一个元组类型的参数,元组的第一个元素为IP地址,第二个元素为端口号。 例如,以下代码将Socket对象绑定到本机的10000端口: ``` # 绑定Socket对象的IP地址和端口号 server_socket.bind(('127.0.0.1', 10000)) ``` 接下来,需要监听Socket对象,接收客户端连接。可以使用Socket对象的listen()函数来实现,该函数需要传入一个整数类型参数,表示最大连接数。 例如,以下代码可以监听来自客户端的连接: ``` # 监听Socket对象,接收客户端连接 server_socket.listen(5) ``` 其,参数5表示最大连接数为5。 最后,接收客户端发送的数据,并返回响应。可以使用Socket对象的accept()函数接收客户端连接。accept()函数会返回一个元组类型的结果,第一个元素为客户端Socket对象,第二个元素为客户端IP地址。 例如,以下代码可以接收客户端发送的数据并返回响应: ``` # 接收客户端发送的数据,并返回响应 while True: client_socket, client_addr = server_socket.accept() data = client_socket.recv(1024) if data: client_socket.send('Hello, client!'.encode('utf-8')) else: break client_socket.close() ``` 其,recv()函数用于接收客户端发送的数据,参数1024表示每次最多接收1024字节的数据。当接收到数据后,可以使用send()函数将数据返回给客户端。 最后,需要关闭Socket对象。可以使用Socket对象的close()函数来关闭Socket对象,释放资源。 以上就是Python实现Socket TCP通信的基本步骤。通过以上步骤,可以实现简单的客户端和服务端之间的网络通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 56
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_End丶断弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值