套接字Socket编程(上)

简介: Socket,原意插座、插口。写软件程序时,可以想象成一根网线,一头插在客户端,一头插在服务端,然后进行通信。所以通信前,双方都要建立一个Socket。

Socket,原意插座、插口。写软件程序时,可以想象成一根网线,一头插在客户端,一头插在服务端,然后进行通信。所以通信前,双方都要建立一个Socket。


Socket编程进行的是端到端的通信,意识不到中间经过多少局域网、路由器,因而能设置参数,也只能是端到端协议之上网络层和传输层的。


在网络层,Socket函数需要指定IPv4 or IPv6,分别对应设置为:

  • AF_INET
  • AF_INET6


还要指定到底是TCP还是UDP:


  • TCP协议是基于数据流的,所以设置为SOCK_STREAM
  • UDP是基于数据报的,因而设置为SOCK_DGRAM

基于TCP协议的Socket程序函数调用过程

两端创建了Socket之后,接下来的过程中,TCP和UDP稍有不同,我们先来看TCP。


TCP的服务端要先监听一个端口,一般是先调用bind函数,给这个Socket赋予一个IP地址和端口。


为什么需要端口?

一个应用程序,当一个网络包来了,内核要通过TCP头里面的这个端口,找到你这个应用程序,把包给你。


为什么要IP地址?

有时一台机器会有多个网卡,就会有多个IP地址。可以选择监听所有网卡,也可以选择监听一个网卡,这样,只有发给这个网卡的包,才会给你。


当服务端有了IP和端口号,就能调用listen函数进行监听。服务端就进入listen状态,这时客户端即可发起连接。


在内核中,为每个Socket维护两个队列:

  • 已经建立了连接的队列,这时候连接三次握手已经完毕,处于established状态
  • 还没有完全建立连接的队列,这时三次握手还没完成,处于syn_rcvd状态。


接着服务端调用accept函数,拿出一个已完成的连接进行处理。若还没完成,就要等着。

在服务端等待时,客户端可通过connect函数发起连接:

  • 先在参数中指明要连接的IP地址和端口号
  • 然后开始发起三次握手
    内核会给客户端分配一个临时端口。一旦握手成功,服务端的accept就会返回另一个Socket


监听的Socket和真正用来传数据的Socket是两个:

  • 监听Socket
  • 已连接Socket


连接建立成功之后,双方开始通过read和write函数来读写数据,就像往一个文件流里面写东西一样。

基于TCP协议的Socket程序函数调用过程。

q.png

TCP的Socket就是一个文件流,因为Socket在Linux中是以文件形式存在。

写入和读出都是通过文件描述符(后文简称为 fd)。


在内核中,Socket是一个文件,那对应就有fd。

每个进程都有一个数据结构task_struct,里面指向一个fd数组,列出该进程打开的所有文件的fd。

fork 之后,就会创建个该结构:


/

struct task_struct {
/* these are hardcoded - don't touch */
  long state; /* -1 unrunnable, 0 runnable, >0 stopped */
  long counter;
  long priority;
  long signal;
  fn_ptr sig_restorer;
  fn_ptr sig_fn[32];
/* various fields */
  int exit_code;
  unsigned long end_code,end_data,brk,start_stack;
  long pid,father,pgrp,session,leader;
  unsigned short uid,euid,suid;
  unsigned short gid,egid,sgid;
  long alarm;
  long utime,stime,cutime,cstime,start_time;
  unsigned short used_math;
/* file system info */
  int tty;    /* -1 if no tty, so it must be signed */
  unsigned short umask;
  struct m_inode * pwd;
  struct m_inode * root;
  unsigned long close_on_exec;
  struct file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
  struct desc_struct ldt[3];
/* tss for this task */
  struct tss_struct tss;
};

fd是个整数,是这个数组的下标。


数组内容是个指针,指向内核中所有打开的文件的列表。是文件,就会有个inode,Socket对应的inode不像真正的文件系统保存在硬盘,而是在内存。在这个inode,指向了Socket在内核中的Socket结构。


这个结构里面,主要是两个队列:

  • 发送队列
  • 接收队列

这两个队列里保存的是一个缓存sk_buff。该缓存能够看到完整的包结构。

1.png

基于UDP协议的Socket程序函数调用过程

UDP没有连接,所以无需三次握手,即无需调用listen、connect。

但UDP的的交互仍需IP、端口号,因而也需要bind。


UDP没有维护连接状态,因而无需每对连接都建立一组Socket,只要有一个Socket就能和多个客户端通信。

正因为没有连接状态,每次通信时,都调用sendto、recvfrom,都可以传入IP地址和端口。

基于UDP协议的Socket程序函数调用过程

1.png


目录
相关文章
|
24天前
|
网络协议 Java
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
这篇文章全面讲解了基于Socket的TCP网络编程,包括Socket基本概念、TCP编程步骤、客户端和服务端的通信过程,并通过具体代码示例展示了客户端与服务端之间的数据通信。同时,还提供了多个案例分析,如客户端发送信息给服务端、客户端发送文件给服务端以及服务端保存文件并返回确认信息给客户端的场景。
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
|
2月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
27 4
|
2月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
49 2
|
2月前
|
网络协议 程序员 视频直播
|
2月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
22 3
|
2月前
|
消息中间件 网络协议 网络安全
Python Socket编程:打造你的专属网络通道,基础篇与进阶篇一网打尽!
【7月更文挑战第26天】在网络编程领域,Python以简洁语法和强大库支持成为构建应用的首选。Socket编程为核心,实现计算机间的数据交换。
50 1
|
2月前
|
安全 网络协议 网络安全
Python Socket编程大揭秘:从菜鸟到黑客的进阶之路,你准备好了吗?
【7月更文挑战第27天】Python Socket编程是网络开发的关键技能,它开启从简单数据传输到复杂应用的大门。Socket作为网络通信的基础,通过Python的`socket`模块可轻松实现跨网通信。
33 0
|
2月前
|
网络协议 Python
告别网络编程迷雾!Python Socket编程基础与实战,让你秒变网络达人!
【7月更文挑战第27天】在网络编程的广阔天地中,Socket编程常被视为一道难关。但用Python这把钥匙,我们可以轻松入门。Socket作为网络通信的基石,在Python中通过`socket`模块封装了底层细节,简化了开发过程。以下是一个基本的TCP服务器与客户端的示例,展示了如何建立连接、收发数据及关闭连接。为了应对实际场景中的并发需求,我们还可以借助多线程技术来提升服务器处理能力。掌握了这些基础知识后,你将逐步揭开网络编程的神秘面纱,踏上编程高手之路!
29 0
|
2月前
|
网络协议 开发者 Python
颠覆传统!Python Socket编程新思维,基础与进阶并重,打造卓越网络能力!
【7月更文挑战第25天】在数字时代,网络通信至关重要,Python的Socket编程简化了这一复杂领域,使初学者也能轻松上手。通过Python的`socket`模块,我们能快速搭建服务器与客户端,实现数据交换。示例代码展示了如何创建、绑定及监听Socket,以及收发消息。掌握基础后,可利用asyncio库探索异步编程,提升通信效率,处理多连接。Python的Socket编程,结合传统与现代技术,助力开发者在网络通信领域取得非凡成就。
40 0
|
2月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
36 0