c语言之Linux网络开发

一、网络编程预备知识 socket IP地址 端口号 字节序 (一)socket 是一个编程接口 是一种特殊的文件描述符 (everything in Unix is a file) 并不仅限于TCP/IP协议 面向连接 (Transmission Control Protocol - TCP/IP) 无连接 (User Datagram Protocol -UDP 和 Inter-network Packet Exchange - IPX) (二)socket类型 1、流式套接字(SOCK_STREAM) 提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按发送顺序接收。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。 2、数据报套接字(SOCK_DGRAM) 提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。 3、原始套接字(SOCK_RAW) 可以对较低层次协议如IP、ICMP直接访问。 (三)socket的位置 (四)IP地址 IP地址是Internet中主机的标识: Internet中的主机要与别的机器通信必须具有一个IP地址 IP地址为32位(IPv4)或者128位(IPv6) 每个数据包都必须携带目的IP地址和源IP地址,路由器依靠此信息为数据包选择路由 表示形式:常用点分形式,如202.38.64.10,最后都会转换为一个32位的无符号整数 (五)端口号 为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区别 TCP端口号与UDP端口号独立 端口号一般由IANA (Internet Assigned Numbers Authority) 管理 众所周知端口:1~1023(1~255之间为众所周知端口,256~1023端口通常由UNIX系统占用) 注册端口:1024~49150 动态或私有端口:49151~65535 (六)字节序 不同类型CPU的主机中,内存存储多字节整数序列有两种方法,称为主机字节序(HBO): 小端序(little-endian) - 低序字节存储在低地址 将低字节存储在起始地址,称为“Little-Endi...

FastAPI后端篇之业务功能开发(二)

 一、功能开发

紧接上篇的功能开发,然后开发出版社、书籍功能。

(一)出版社功能开发

1、开发出版社功能的API

  • 根据出版社名称查找出版社信息
  • 创建一个出版社信息
  • 获取所有出版社信息

2、请求与响应模型设计

       设计请求响应模型对用户发送的请求体以及服务器返回的响应体进行校验,在schemas.py文件中:
from pydantic import BaseModel, EmailStr from datetime import datetime from typing import Optional class PublishBase(BaseModel): name: str # 请求体模型校验 class PublishCreate(PublishBase): pass # 响应体模型校验 class Publish(PublishBase): id: int class Config: orm_mode = True

3、工具类开发 

对用户提交的请求体进行操作,增删查改,在crud.py文件中:
from sqlalchemy.orm import Session import models, schemas from typing import List # 通过出版社名字获取具体的信息 def get_publish_by_name(db: Session, name: str): return db.query(models.Publish).filter(models.Publish.name == name).first() # 创建一个出版社信息 def create_publish(db: Session, publish: schemas.PublishCreate): db_publish = models.Publish(**publish.dict()) db.add(db_publish) db.commit() db.refresh(db_publish) return db_publish # 获取所有的出版社信息 def get_all_publish(db: Session): return db.query(models.Publish).all()

4、创建视图函数

在main.py文件中:
from fastapi import FastAPI, Depends, HTTPException import uvicorn import schemas, crud from sqlalchemy.orm import Session from dependencies import get_db from typing import List app = FastAPI() # 创建一个出版社信息 @app.post("/publisher", response_model=schemas.Publish) def create_publish(publish: schemas.PublishCreate, db: Session = Depends(get_db)): db_publish = crud.get_publish_by_name(db, publish.name) if db_publish: raise HTTPException(status_code=400, detail="publish already exists!") return crud.create_publish(db, publish) # 获取所有出版社信息 @app.get("/publishers", response_model=List[schemas.Publish]) def get_all_publishs(db: Session = Depends(get_db)): return crud.get_all_publish(db) if __name__ == '__main__': uvicorn.run(app=app, host="127.0.0.1", port=8080)
启动后就可以直接访问了。

(二)书籍功能开发

1、开发书籍功能的API 

  • 根据书籍名称查找出书籍信息 
  • 创建一本书籍信息 
  • 获取所有书籍信息 

2、请求与响应模型设计 

设计请求响应模型对用户发送的请求体以及服务器返回的响应体进行校验,在schemas.py文件中:
from pydantic import BaseModel, EmailStr from datetime import datetime from typing import Optional class BookBase(BaseModel): title: str price: float publish_date: Optional[datetime] = None # 创建一个书籍信息 class BookCreate(BookBase): pass # 获取所有书籍信息 class Book(BookBase): author_id: int class Config: orm_mode = True

3、工具类开发 

对用户提交的请求体进行操作,增删查改,在crud.py文件中:
from sqlalchemy.orm import Session import models, schemas from typing import List # 根据作者id、出版社id列表来创建书籍信息,包括外键以及多对多关系表 def create_book_by_author(db: Session, book: schemas.BookCreate, author_id: int, publish_id_list: List[int]): db_book = models.Book(**book.dict(), author_id=author_id) # 根据publish_id_list生成对象列表 publish_obj_list = [db.query(models.Publish).filter(models.Publish.id == i).first() for i in publish_id_list] db_book.book_to_publish = publish_obj_list db.add(db_book) db.commit() db.refresh(db_book) return db_book # 根据书籍名称查找书籍 def get_book_by_title(db: Session, title: str): return db.query(models.Book).filter(models.Book.title == title).first() # 获取所有的书籍信息 def get_all_books(db: Session): books = db.query(models.Book).all() result = [] for obj in books: result.append({ "id": obj.id, "title": obj.title, "price": obj.price, "publish_date": obj.publish_date, "authors": obj.book_to_author, "publishs": obj.book_to_publish }) return result

4、创建视图函数 

在main.py文件中:
from fastapi import FastAPI, Depends, HTTPException import uvicorn import schemas, crud from sqlalchemy.orm import Session from dependencies import get_db from typing import List app = FastAPI() # 根据作者以及出版署参数创建书籍信息 @app.post("/book/{author_id}", response_model=schemas.Book) def create_book(author_id: int, publish_id_list: List[int], book: schemas.BookCreate, db: Session = Depends(get_db)): db_book = crud.get_book_by_title(db=db, title=book.title) if db_book: raise HTTPException(status_code=400, detail="book already exists!") return crud.create_book_by_author(db=db, book=book, author_id=author_id, publish_id_list=publish_id_list) # 获取所有的书籍信息 @app.get("/books") def get_all_books(db: Session = Depends(get_db)): return crud.get_all_books(db) if __name__ == '__main__': uvicorn.run(app=app, host="127.0.0.1", port=8080)
启动后就可以直接访问了。

二、自定义响应模型 

       在之前的响应中,返回的就是数据库中的数据,没有带一些返回给前台的信息,所以响应信息不完善,那么正常的是返回一些信息然后加上数据。 

1、自定义Pydantic模型 

在schemas.py文件中新建三个模型:
# 书籍响应体单独定义 class BookAll(BaseModel): id: int title: str price: float publish_date: datetime authors: Author publishs: List[Publish] # 自定义响应模型,获取所有的数据 class GeneralResDefine(BaseModel): message: str code: int data: List[Union[Author, Publish, BookAll]] # 创建成功数据模型,返回创建成功的那个对象 class GeneralDefine(BaseModel): message: str code: int obj: Union[Author, Publish, BookAll]

2、视图函数 

 在main.py文件中:
from fastapi import FastAPI, Depends, HTTPException import uvicorn import schemas, crud from sqlalchemy.orm import Session from dependencies import get_db from typing import List, Union from fastapi.encoders import jsonable_encoder from fastapi.responses import JSONResponse # import models # from database import engine # # models.Base.metadata.create_all(bind=engine) app = FastAPI() @app.get("/") async def home(): return {"username": "zhangsan"} @app.post("/author", response_model=Union[schemas.Author, schemas.GeneralDefine]) def create_author(author: schemas.AuthorCreate, db: Session = Depends(get_db)): res = { "message": "创建成功", "code": 200, "obj": {} } db_author = crud.get_author_by_username(db, author.username) if db_author: raise HTTPException(status_code=400, detail="author already exists!") try: obj = crud.create_author(db, author) res["obj"] = obj except Exception as e: res["message"] = "创建失败" res["code"] = 208 return res @app.get("/authors", response_model=Union[List[schemas.Author], schemas.GeneralResDefine]) def get_all_authors(db: Session = Depends(get_db)): res = { "message": "获取成功", "code": 200, "data": [] } try: result = crud.get_all_author(db) res["data"] = result except: res["message"] = "获取失败" res["code"] = 208 return res @app.post("/publisher", response_model=Union[schemas.Publish, schemas.GeneralDefine]) def create_publish(publish: schemas.PublishCreate, db: Session = Depends(get_db)): res = { "message": "创建成功", "code": 200, "obj": {} } db_publish = crud.get_publish_by_name(db, publish.name) if db_publish: raise HTTPException(status_code=400, detail="publish already exists!") try: obj = crud.create_publish(db, publish) res["obj"] = obj except Exception as e: res["message"] = "创建失败" res["code"] = 208 return res @app.get("/publishers", response_model=Union[List[schemas.Publish], schemas.GeneralResDefine]) def get_all_publishs(db: Session = Depends(get_db)): res = { "message": "获取成功", "code": 200, "data": [] } try: result = crud.get_all_publish(db) res["data"] = result except: res["message"] = "获取失败" res["code"] = 208 return res @app.post("/book/{author_id}", response_model=Union[schemas.Book, schemas.GeneralDefine]) def create_book(author_id: int, publish_id_list: List[int], book: schemas.BookCreate, db: Session = Depends(get_db)): res = { "message": "创建成功", "code": 200, "obj": {} } db_book = crud.get_book_by_title(db=db, title=book.title) if db_book: raise HTTPException(status_code=400, detail="book already exists!") try: obj = crud.create_book_by_author(db=db, book=book, author_id=author_id, publish_id_list=publish_id_list) res["obj"] = obj except Exception as e: res["message"] = "创建失败" res["code"] = 208 return res @app.get("/books", response_model=schemas.GeneralResDefine) def get_all_books(db: Session = Depends(get_db)): res = { "message": "获取成功", "code": 200, "data": [] } try: result = crud.get_all_books(db) res["data"] = result except: res["message"] = "获取失败" res["code"] = 208 return res if __name__ == '__main__': uvicorn.run(app=app, host="127.0.0.1", port=8010)

3、创建书籍工具类 

在创建书籍函数中之前没有返回与之相关的出版社信息,这里进行返回出版社信息,在crud.py文件中:
def create_book_by_author(db: Session, book: schemas.BookCreate, author_id: int, publish_id_list: List[int]): db_book = models.Book(**book.dict(), author_id=author_id) # 根据publish_id_list生成对象列表 publish_obj_list = [db.query(models.Publish).filter(models.Publish.id == i).first() for i in publish_id_list] db_book.book_to_publish = publish_obj_list db.add(db_book) db.commit() db.refresh(db_book) obj = { "id": db_book.id, "title": db_book.title, "price": db_book.price, "publish_date": db_book.publish_date, "authors": db_book.book_to_author, "publishs": db_book.book_to_publish } return obj


更多文章合集前往: 往期精彩文章

此博客中的热门博文

玩转虚拟机系列之如何搭建虚拟机

玩转虚拟机系列之远程工具

玩转虚拟机系列之如何高效创建虚拟机