我的编程空间,编程开发者的网络收藏夹
学习永远不晚

第33天 初识socket编程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

第33天 初识socket编程

目录

  1. OSI七层模型简介

  2. 网络编程简介

  3. socket编程简介

  4. 使用socket进行网络编程

  5. 基于tcp的socket编程

  6. TCP粘包问题

  7. 基于udp的socket编程

一. OSI七层模型简介

  从下图中我们可以看到OSI七层模型中规定的几个特殊的名词:

  MAC:  mac地址是在每一个计算机出厂的时候就会烧录进网卡内的一串数字,用来唯一的表示一台计算机

  IP:  ip地址根据你所在的网络的不同而不同,主要是用来标识一个局域网。

  PORT:端口号的范围是0-65535,主要是用来标识唯一的一个应用软件。

  通过以上mac和ip我们可以在全世界找到唯一的一台计算机,然后再通过port我们可以找到计算机内的唯一的一个应用程序,从而完成两台计算机应用程序之间的交互。

二. 网络编程简介

  什么叫做网络编程呢?在之前我们写程序的时候,所有的程序都是在一台机器之上的,所以我们不需要考虑通过internet去交互数据。但是在日常的开发过程中,我们写的程序大都不是在一台机器之上的,这就会出现一个问题,如果程序不在一台机器之上,我们应该通过什么进行通信呢?那就是网络,而我们把这种编程的方式称之为网络编程。下面是网络编程的两种架构

c/s架构
  c:客户端
  s: 服务器
  典型的应用:qq,微信,王者荣耀
b/s架构
  b: 浏览器
  s: 服务器
  典型的应用: Google,火狐等

三. socket编程简介

  socket是什么呢?socket编程其实就是网络编程。如下图,socket并不是一个真实存在的协议或者标准,它只是应用层与tcp/ip软件协议簇通信的中间软件抽象层。更准确的来说它就是别人规定好的一个模块,这个模块给我们封装了一系列的接口,可以让我们很方便的进行网络编程,而不用去深究我们应该怎么去写一个三次握手,四次挥手或者报文封装之类的复杂操作。

  虽然socket编程给我们封装了一系列的接口,但是并不代表我们就不需要去学习底层的协议。

四. 使用socket进行网络编程

  socket编程一般是有两个程序的,一个是服务端,一个是客户端,一个简单的socket编程用到方法如下图。

  

案例: 接下来我们以打电话为例来简单的介绍一下socket程序

步骤0:初识代码

import socket  # 导入了模块

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 首先我去买个手机
phone.bind(('127.0.0.1', 8080)) # 给我的手机插一张卡,('127.0.0.1', 8080)
phone.listen(5) # 开始给我的手机装电池进行开机
conn, addr = phone.accept() # 开机之后我随时等待着有人打电话过来
data = conn.recv(1024)  # 先听一下对面说什么
conn.send('hello'.encode('utf-8'))  # 然后给对面回复一个内容

conn.close()  # 话讲完了之后我要按一下挂断才能挂断电话
phone.close()  # 今天有点累了,把手机调成飞行模式,不想接电话了

 步骤一: 创建一个socket对象

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
参数一:定义的是套接字家族
  套接字家族其实分为两种,在最初unix开发出来的时候套接字其实为了解决进程间通信的,也就是通常所说的基于文件的套接字家族。随着计算机的发展,网络间的通信越来越频繁,因此慢慢的形成了另外一个家族,那就是基于网络的套接字家族,我们现在所学习的套接字基本山都是基于网络的套接字家族
  socket.AF_INET: 基于网络的套接字家族
  socket.AF_UNIX: 基于文件的套接字家族
参数二:定义的是传输层使用的协议
  socket.SOCK_STREAM:使用tcp协议
  socket.SOCK_DGRAM: 使用的是udp协议

步骤二: 绑定ip和端口

phone.bind(('127.0.0.1', 8080))
解释:bind操作只有在服务端才会出现,为了通知客户端此时服务端在网络的哪个位置,以及是哪个应用。
参数:套接字地址(也就是ip+端口)

ip: ip就是运行此服务的计算机的ip地址,此处的127.0.0.1是一个特殊的回环地址,用来表示本机,一般用来测试代码用的。
port: 端口用来表示是哪个应用程序。 1-1023用来给系统使用,1024-65535我们可以正常的使用,但是一般要避免使用约定俗成的一些端口,如数据库的端口3306。

步骤三:监听

phone.listen(5)  # 用来监听的
参数:定义的是半连接池的大小

5: 代表的就是半连接池只有5个,如果超过5个,将直接拒绝连接。注意,此处的半连接数量指的并不是已经建立了tcp连接的数量。

 半连接池数的例子:

# 服务端代码

import  socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)  # 此处定义半连接数为5,也就是当前没有连接成功的数量必须小于等于5
while True:
    conn, addr = server.accept()
    while True:
        try:
            res = conn.recv(1024)
            print('服务端发送的数据', res)
        except Exception as e:
            print(e)
            break
    conn.close()


# 客户端
import  socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>>:')
    client.send(msg.encode('utf-8'))端代码
测试代码

当我连接了第七个客户端的时候就会报错,为什么呢?

1. 第一个客户端发送syn请求的时候,首先进入了半连接池内,此时服务端空闲,因此是可以进行三次握手的,因此服务端将此连接从半连接池中拿出来,然后进行三次握手,然后进行通信。

2. 第二个客户端紧接着也发送了syn请求,它也进入了半连接池内,但是此时的服务端在忙着和客户端一进行通信,因此第二个客户端就等待着服务端结束了与第一个通信之后过来和自己通信,第三个客户端第四个。。都是一样的。

3. 当第七个客户端发送了syn请求之后,服务端发现现在我的半连接池里面已经有了五个客户端在等待了,而listen的参数也是五,不能再接受请求了,因此立即给你回复一个报文告诉你不能连接,也就是下图中的错误了。

步骤四:接收一个连接

conn, addr = phone.accept()
解释:当代码执行到这一步的时候,程序就会阻塞,就像input函数在等待输入一样,它在等待着一个连接,当一个连接到来的时候,会返回一个元组,元组的内容为双向连接的对象,和一个地址。

conn: 接收一个连接之后就相当于建立了一根管道,此管道是服务端和客户端共同维持的,我们可以通过conn去发送和接受数据
addr: (ip, port),这个地址指的是当前连接的客户端的地址和端口

步骤五: 接收数据

data = conn.recv(1024) 
解释:代表从管道conn中接收一个最大为1024的数据。

参数:此处的1024代表的是最大一次能从系统缓存中得到的字节数。
举例一:系统缓冲区中有1025个字节,如果用conn.recv(1024)去取,就只能取到1024个字节,剩余的一个字节还留在系统缓冲区
举例二:系统缓冲区有25个字节,如果用conn.recv(1024)去取,能够取完25个字节,此时系统缓冲区没有字节。

步骤六: 发送数据

conn.send('hello'.encode('utf-8'))
解释:就是通过管道conn将数据发送给客户端

注意:在socket编程中发送和接收的数据都是字节,因此在发送和接收的时候我们需要对其进行编码和解码。

五. 基于tcp的socket编程

1. 简单实现套接字通信

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
conn, addr = server.accept()
data = conn.recv(1024)
conn.send(data.upper() + b'sb')
服务端代码
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
msg = input('>>')
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print('服务器回复的数据', data)
客户端代码

以上代码可以完成一个简单的通信过程,当客户端输入一串字符之后,服务端都会在后面加上sb两个字符返回回来。

2. 循环通信

虽然实现了一个简单的通信,但是在日常生活中我们说一句话之后,就会挂电话吗,当然不会,我们希望的是通过一个循环可以让我模拟出我们可以不停的发送信息然后服务端给我回复信息,因此代码可以修改成下面的样子。

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>')
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print('服务器回复的数据', data)
客户端程序
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
conn, addr = server.accept()
while True:
    data = conn.recv(1024)
    conn.send(data.upper() + b'sb')
服务端程序

问题一: 当我们输入为空的时候,客户端和服务端都会进入等待状态

  机制: Python默认是不会发送空数据到服务端的。

  客户端:所以当客户端输入为空,执行send时发现数据为空,就直接跳过此语句,此时客户端开始执行recv语句,也就是进入了阻塞阶段,等待接收数据,但是此时并没有人给我发数据,所以阻塞了。

  服务端:因为一直没有收到客户端的数据,因此也一直阻塞状态中

  解决方法:我们可以在send之前判断输入是否为空,如果为空,则continue

问题二:当把客户端异常退出的时候,服务端也异常退出

  服务端与客户端在连接成功的那一刻会返回一个conn对象,这个对象是客户端和服务端同时维护的,因此无论是哪一方异常断开都会出现异常。

  解决方法: 在服务端进行捕捉异常,如果捕捉到异常,则关闭当前连接,继续接受其他的连接。

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
conn, addr = server.accept()
while True:
    # 在此处捕捉异常,一旦捕捉到异常则退出循环关闭当前连接
    try:
        data = conn.recv(1024)
        conn.send(data.upper() + b'sb')
    except Exception as e:
        print(e)
        break
conn.close()
server.close()
修改后的服务端代码
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>')
    if not msg:
        continue
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print('服务器回复的数据', data)
修改后的客户端代码

3. 循环连接

  在我们上面修改代码的基础上,当客户端关闭之后,服务端虽然不会进行报错了,但是还是会退出来,为了让他循环连接,所以再加一个循环,实现客户端退出之后,将不会影响服务端下次的连接

服务端:

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
while True:   conn, addr = server.accept()   while True:    # 在此处捕捉异常,一旦捕捉到异常则退出循环关闭当前连接   try:    data = conn.recv(1024)    conn.send(data.upper() + b'sb')   except Exception as e:    print(e)    break   conn.close() server.close()

客户端:

import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>')
    if not msg:
        continue
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print('服务器回复的数据', data)

六.  TCP粘包问题

1. 什么是粘包

  两个应用程序在交互数据的时候并不是直接进行交互的,如下图所示。

  发送过程:应用程序要把数据首先存放在操作系统的缓冲区,然后由操作系统去调用网卡接口将数据转发出去。

  接收过程:网卡接收到数据之后首先要存放在操作系统的缓冲区,然后才是由应用程序过来取。

  粘包:指的是连续发送两个不相干的数据包,但是应用程序却没有来得及收,从而导致两个不相干的数据包一起存在操作系统缓冲区而无法区分的问题。

2. 为什么会出现粘包这个问题

  因为对于操作系统而言,每接收一个数据包就会在之前数据存储的后面继续存储数据,并不会给两个数据包区分一个明显的界限,因此当上一次的数据没有取完的时候,一旦操作系统重新接收到了新的数据,就会出现粘包的问题。

3. 粘包的现象

import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
while True:
    conn, addr = server.accept()
    while True:
        try:
            data = conn.recv(1024)
            conn.send(data.upper() + b'sb')
        except Exception as e:
            print(e)
            break
    conn.close()
server.close()
上面写好的服务端代码
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>')
    if not msg:
        continue
    client.send(msg.encode('utf-8'))
    data = client.recv(5)   # 此时接收的字节数改变了
    print(data)
上面写好的客户端代码,把接收的字节数改成了5,用来实验

执行客户端测试原理:

我们可以让客户端的代码睡一觉,就会出现另外一种结果:

4. 处理粘包的三种方式

<1>.time.sleep()发送完数据之后主动让代码睡一会

time.sleep()只能在某一种情况下去解决粘包的问题,在数据量较大的时候也不能解决粘包的问题,而且我们也并不建议这样子去做。

<2>.增大recv()的参数值

这个方法确实是可以在一定程度上解决粘包的问题,但是应用程序缓冲区的大小并不是你想要多大就多大的,而且,参数值得也是有限制的,因此,我们也不建议这样子去做。

<3>.在发送数据之前发送一下数据的长度 

远程执行命令的小程序

import socket
import subprocess
import struct

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 65535))
server.listen(5)
while True:
    conn, addr = server.accept()
    while True:
        try:
            cmd = conn.recv(1024)
            print(cmd)
            obj = subprocess.Popen(
                cmd.decode('utf-8'),
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            print(obj)
            # 注意此处的stdout和stderr不能位置不能相反,必须先读out后读err
            stdout = obj.stdout.read()
            print(stdout)
            stderr = obj.stderr.read()
            print(stderr)
            # 计算数据的长度,返回的是一个字节,在客户端先读取四个字节获得数据长度
            head = struct.pack('i', len(stderr + stdout))
            print(head)
            # 拼接数据,并进行发送
            data = head + stderr + stdout
            print(len(stdout) + len(stderr))
            conn.send(data)
        except Exception as e:
            print(e)
            break
    conn.close()
服务端程序
import socket
import struct
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 65535))
while True:
    msg = input('>>')
    if not msg:
        continue
    client.send(msg.encode('utf-8'))
    head = client.recv(4)    # 获得报头
    total_len = struct.unpack('i', head)[0]  # 将报头中前四个字节解压得到数据的总长度
    current_len = 0    # 当前读取的报文长度
    data = b''
    finally_data = b''
    while current_len < total_len:
        print(current_len, total_len)
        data = client.recv(1024)
        current_len += len(data)
        finally_data += data
    print(finally_data.decode('gbk'))
客户端程序

5. 自定义报头

自定义报头和我们之前说的那个远程执行命令的小程序很相似,只是在客户端进行解析的时候需要通过两步去操作,一个就是分析报头,一个就是分析数据包真实的内容。
"""客户端传过来一个名字,复制这个文件到客户端上面,并且在自定义一个文件头传递过去"""

import socket
import hashlib
import struct
import json

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
    conn, addr = server.accept()
    while True:
        try:
            file_name = conn.recv(1024)  # 获得一个字节形式的文件名
            # print(file_name)
            hash_value = hashlib.md5()   # 当前文件的hash值
            file_data_bytes = b''  # 存储文件的数据
            with open(file_name.decode('utf-8'), 'rb') as f:
                for line in f:
                    file_data_bytes += line
                    hash_value.update(line)

            # 自定义文件头
            head_dict = {
                'name': file_name.decode('utf-8'),
                'md5': hash_value.hexdigest(),
                'file_data_len': len(file_data_bytes)
            }
            print(head_dict)
            # 用json转换当前文件头为字节形式
            head_bytes = json.dumps(head_dict).encode('utf-8')

            # 计算当前文件头的长度,并且转换成固定长度(i为4)的字节形式
            head_len_bytes = struct.pack('i', len(head_bytes))

            # print(head_len_bytes,)

            # 发送数据
            conn.send(head_len_bytes + head_bytes + file_data_bytes)

        except Exception as e:
            print(e)
            break
    conn.close()
服务端程序
import json
import socket
import struct
import os

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8080))

temp = '请'
while True:
    file_name = input(temp + '输入你要下载的文件名称(Q退出)>>>').strip()
    file_name = 'H:\python_study\day34\自定义\客户端.py'
    if file_name.upper() == 'Q':
        break
    if not file_name:
        print('输入不能为空')
        temp = '请重新'
        continue
    client.send(file_name.encode('utf-8'))
    # print(client.recv(100))
    # 读取文件头的内容
    head_len = struct.unpack('i', client.recv(4))[0]  # 获取文件头的长度
    print(head_len)
    head_data_bytes = b''
    while head_len > 0:
        if head_len - 10 > 0:
            head_data_bytes += client.recv(10)
        else:
            head_data_bytes += client.recv(head_len)
        head_len -= 10
    print(head_data_bytes.decode('utf-8'))
    head_data_dict = json.loads(head_data_bytes.decode('utf-8'))
    print(head_data_dict)
    # 读取真实的文件数据并且进行保存
    file_data_len = head_data_dict['file_data_len']
    file_data_bytes = b''
    while file_data_len > 0:
        file_data_bytes += client.recv(10)
        file_data_len -= 10

    file_path = os.path.normpath(os.path.join(
        __file__,
        os.pardir,
        '下载',
        os.path.basename(head_data_dict['name'])
    ))
    with open(file_path, 'wb') as f:
        f.write(file_data_bytes)
client.close()
客户端程序

七. 基于udp的socket编程

1. 简单的实现套接字的通信

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))   # 和tcp一样需要去绑定ip和端口,但是它不必像tcp一样去监听和接收连接
conn = server.recvfrom(1024)  # 直接recvfrom就可以了
print(conn)

# 结果:
# (b'hello', ('127.0.0.1', 55802))   会获得一个地址和数据
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.sendto('hello'.encode('utf-8'), ('127.0.0.1', 8080))  # 客户端需要发送数据的时候需要添加一个ip和端口

2. 实现循环通讯

import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))   # 和tcp一样需要去绑定ip和端口,但是它不必像tcp一样去监听和接收连接
while True:
    data, addr = server.recvfrom(1024)  # 直接recvfrom就可以了
    server.sendto(data.upper(), addr)
服务端程序
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
    msg = input('>>>')
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))  # 客户端需要发送数据的时候需要添加一个ip和端口
    data, addr = client.recvfrom(1024)
    print('服务器发送过来的数据>', data.decode('utf-8'))
客户端程序

3. 实现两个客户端之间的通信

思路:每一个给服务器发送过数据的客户端都会在服务器上面保存一个地址,然后等下次客户端再给服务器发送数据的时候,服务器就会将客户端的消息发送给所有的客户端
import socket

server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server.bind(('127.0.0.1', 8080))   # 和tcp一样需要去绑定ip和端口,但是它不必像tcp一样去监听和接收连接

client_set = set({})
while True:
    data, addr = server.recvfrom(1024)  # 直接recvfrom就可以了
    client_set.add(addr)
    for client in client_set:
        server.sendto(data, client)
服务器端代码
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
    msg = input('>>>')
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))  # 客户端需要发送数据的时候需要添加一个ip和端口
    data, addr = client.recvfrom(1024)
    print('服务器发送过来的数据>', data.decode('utf-8'))
客户端代码都是一样的

 4. udp的recvfrom(512)参数的意义

import socket

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input('>>')
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
服务端代码
import socket

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input('>>')
    client.sendto(msg.encode('utf-8'), ('127.0.0.1', 8080))
客户端代码
windows:
  当我们在客户端输入12345678910也就是发送超过十个字节之后,就会报错。如下图
linux:
  不会报错,但是会丢包,也就是只会收到10个字节,其他的字节都不收了。

注意:一般我们只会把此处的值设置成512,因为对于udp而言,如果一旦接收的字节超过512之后,就会极易出现丢包的现象。

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

第33天 初识socket编程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

第33天 初识socket编程

目录  1. OSI七层模型简介  2. 网络编程简介  3. socket编程简介  4. 使用socket进行网络编程  5. 基于tcp的socket编程  6. TCP粘包问题  7. 基于udp的socket编程一. OSI七层模
2023-01-30

网络编程知识-socket

一、 C/S 架构:Client/Server   客户端/ 服务端  B/S 架构:Browser/Server  前端/ 服务端    网卡--> mac地址-->ip地址-->子网掩码-->网关-->DNS服务器(进行域名domain
2023-01-31

初试python的socket编程--ftp

server端: #_*_coding:utf-8_*_ import SocketServerimport osimport commandsclass MyTCPHandler(SocketServer.BaseRequestHandl
2023-06-02

gui编程 -- tkinter初识

Tkinter 编程Tkinter: Tkinter 模块(Tk 接口)是 Python 的标准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macint
2023-01-30

初识网络编程

c/s b/s 架构client 客户端/server 服务端browser 浏览器/server 服务端现在多数都是客户端与服务端之间进行交互,获取信息但像微信小程序,支付宝等一些应用都开始发展小程序功能,通过微信就可直接在内部调用其他程
2023-01-31

Socket编程的知识点有哪些

这篇文章主要介绍“Socket编程的知识点有哪些”,在日常操作中,相信很多人在Socket编程的知识点有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Socket编程的知识点有哪些”的疑惑有所帮助!接下来
2023-06-17

Socket编程简单示例(聊天服务器)

socket编程是在不同的进程间进行网络通讯的一种协议,下面这篇文章主要给大家介绍了关于Socket编程简单示例的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2023-02-18

第37天并发编程之线程篇

一. 线程初识什么是线程和进程进程指的是一个程序执行的过程,是一个资源单位。它包含了操作系统开辟内存空间,将应用程序加载到内存中以及执行应用程序代码的整个过程。就像是一个车间内的一个小工厂一样,整个的生产过程被称之为一个进程。线程是操作系统
2023-01-30

【网络编程】网络编程 和 Socket 套接字认识

✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 目 录 🎧一. 网络编程基础🎺1. 为什么需要网络编程?🎷2.
2023-08-23

第36天并发编程之进程篇

目录:  1. 基础概念  2. 创建进程和结束进程  3. 进程之间内存空间物理隔离  4. 进程的属性方法  5. 守护进程  6. 互斥锁  7. IPC通信机制  8. 生产者消费者模型一. 基础概念1. 什么叫做程序,什么叫做进程
2023-01-30

SAP ABAP编程 取月份的最后一天or第一天

DATA: FIR_DATA TYPE SY-DATUM. "第一天DATA: LAS_DATA TYPE SY-DATUM. "最后一天FIR_DATA = SY-DATUM.LAS_DATA = SY-DATUM.FIR_DAT
2023-06-05

学习python的第一天(编程,计算机组

一.Typora关于用Typora 自我感觉良好,基本快捷键也比较简单,ps:还是要多用用二.编程1.编程语言是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令。(来自百度百科对于编程语言的诠释)我个人理解,编
2023-01-31

初识计算机和编程简单运用

1.计算机有哪些东西内部:cpu中央处理器     内存   主板  电源外部:键盘  鼠标  显示器  显卡   硬盘 计算器是一个高度集成的电子电路:高低电平 ,二进制,八进制,十六进制显卡:NAVID  用于游戏AMD   图形处理 
2023-01-30

Java 中怎么利用Socket编程识别网络主机

这期内容当中小编将会给大家带来有关Java 中怎么利用Socket编程识别网络主机,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。获取主机地址信息在Java中我们使用InetAddress类来代表目标网络地
2023-06-17

学习python的第十八天(面向对象编程

一.面向对象编程​ 面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、然后干什么……与工厂的工艺流程差不多,前后都有影响优点:复杂的问题流程化,进而简单化,调理清晰.缺点:拓展性不行二.对于我之前写的一
2023-01-31

Python编程判断这天是这一年第几天的方法示例

本文实例讲述了Python编程判断这天是这一年第几天的方法。分享给大家供大家参考,具体如下: 题目:输入某年某月某日,判断这一天是这一年的第几天? 实现代码:year=int(input('请输入年:')) month=int(input(
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录