前言

研一的时候写过socket网络编程,研二这一年已经在用php写api都快把之前的基础知识忘干净了,这里回顾一下,主要也是项目里用到了,最近博客好杂乱啊,不过确实是到了关键时刻,各种复习加巩固准备9月份校招,顺便优美的完成手里的项目

概述

socket这个词可以有很多概念:
  • 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通迅中的一个进程,“IP地址+端口号”就称为socket
  • 在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成的socket pair就是唯一标识一个连接。socket本身有“插座”的意思,用来描述网络连接中一对一关系
  • TCP/IP协议最早是BSD UNIX上实现,为TCP/IP协议设计的应用层编程接口称为socket API

预备知识

发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按照内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定: 先发出去的数据是低地址,后发出去的数据是高地址

TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。例如UDP段格式,地址0-1是16位的源端口号,如果这个端口号是1000(0x3e8),则地址0是0x03,地址1是0xe8,也就是先发0x03,再发0xe8,这16位在发送主机的缓冲区中也应该是低地址存0x03,高地址存0xe8
为了网络程序具有可移植性,使同样的c代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换
#include <arpa/inet.h>/*h表示host,n表示network, htonl表示将32位长整数从主机字节序转换为网络字节序*/
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

socket地址的数据类型以及相关函数

socket API是一层抽象的网络编程接口,适用于各种底层网络协议,如IPV4,IPV6,UNIX Domain Socket
ipv4地址的数据结构 struct sockaddr_in:

基于TCP协议的网络程序

TCP协议通迅流程:
服务器调用socket()、bind()、listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后,调用connect()发出SYN段并阻塞等到服务器应答,服务器应答一个SYN-ACK段,客户端收到后从connect()返回,同时应答一个ACK段,服务器收到后从accept()返回
数据传输过程
建立连接后,TCP提供全双工的通信服务,但是一般的客户端/服务器程序的流程是由客户端主动发起请求,服务器被动处理,一问一答的方式。因此,服务器从accept()返回后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待,这时客户端调用write()发送请求给服务器,服务器收到后从read()返回,对客户端的请求进行处理,在此期间客户端调用read()阻塞等待服务器的应答,服务器调用write()将处理结果发回给客户端,再次调用read()阻塞等待下一条请求,客户端收到后从read()返回,发送下一条请求,如此循环下去
如果客户端没有更多的请求了,就调用close()关闭连接,就像写端关闭管道一样,服务器的read()返回0,这样服务器知道客户端关闭了连接,也调用close()关闭连接

简单的TCP网络程序

先写一个服务器端的监听程序,作用是从客户端读取字符,拼上自定义的字符串返回给客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define MAXLINE 80
#define SERV_PORT 9933int main(void)
{struct sockaddr_in servaddr, cliaddr;  // 服务器和客户端的socket数据结构// typedef int socklen_t;// typedef int ssize_t;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];// 创建socket,返回整形socket标识// domain = AF_INT : 套接字指定IPV4网络协议集// type = SOCK_STREAM : 可靠的面向流服务器或套接字// protocol = 0, 选择缺省的传输协议listenfd = socket(AF_INET, SOCK_STREAM, 0);// 为服务器的sockaddr_in数据结构分配内存地址memset(&servaddr, 0, sizeof(servaddr));// 为服务器套接字指定协议族servaddr.sin_family = AF_INET;// 为服务器套接字指定ip,INADDR_ANY = 0.0.0.0servaddr.sin_addr.s_addr = htonl(INADDR_ANY);// 为服务器套接字指定portservaddr.sin_port = htons(SERV_PORT);  // 为一个套接字分配地址,使用socket()创建套接字后,// 只赋予其使用的协议,并未分配地址,bind()用来为listenfd// 分配地址,参数解释:// sockfd = listenfd, bind函数的套接字描述符// my_addr = &servaddr, 服务器端sockaddr结构的指针// addrlen = sizeof(servaddr), sockaddr结构的长度bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));// socket监听,准备接受连接请求listen(listenfd, 20);printf("王正一的server服务器开始等待客户端连接 ...\n");while (1) {cliaddr_len = sizeof(cliaddr);// 三次握手完成后,服务器调用accept()接受客户端连接// accept()参数:// sockfd = listenfd, 服务器端监听的套接字描述符// cliaddr = &cliaddr, 指向sockaddr结构体指针,客户端// 的地址信息// addrlen = &cliaddr_len,确定客户端地址结构体的大小connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);read(connfd, buf, MAXLINE);printf("从客户端%s的%d端口收到数据\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));strcat(buf, "从王正一机器返回的信息");write(connfd, buf, MAXLINE);close(connfd);}
}

运行状态:

在写一个客户端通过socket通信向服务器发送数据的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define MAXLINE 80
#define SERV_PORT 9933int main(int argc, char *argv[])
{// 需要连接的服务器端socket套接字// 客户端的socket套接字由系统自动分配struct sockaddr_in servaddr;char buf[MAXLINE];int servfd;char *str;if (argc != 2) {printf("使用方法:./client 发送的字符串\n");return 1;}str = argv[1];servfd = socket(AF_INET, SOCK_STREAM, 0);memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr("222.31.79.131");  // 传媒ipservaddr.sin_port = htons(SERV_PORT);// 客户端调用connect连接服务器端指定socket套接字connect(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr));write(servfd, str, strlen(str));read(servfd, buf, MAXLINE);printf("从服务器返回的信息为:%s", buf);close(servfd);return 0;
}

运行状态:

ok,基本完成了一个简单的TCP通信过程!!

使用fork并发处理多个client的请求

网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端。但是子进程退出时会产生僵尸进程,父进程要注意处理SIGCHLD信号和调用wait清理僵尸进程

Linux C编程一站式学习读书笔记——socket编程相关推荐

  1. Java并发编程之美读书笔记-并发编程基础2

    2019独角兽企业重金招聘Python工程师标准>>> 1.线程的通知与等待 Java中的Object类是所有类的父亲,鉴于继承机制,Java把所有类都需要的方法放到了Object类 ...

  2. Linux C编程一站式学习笔记2

    Linux C编程一站式学习笔记 chap2 常量.变量和表达式 本书以C99为标准 一.继续hello world 加入更多注释的hello world 可以用ctrl+(shift)+v复制到vi ...

  3. linux c一站式编程 pdf,《Linux·C编程一站式学习》·(宋劲杉)·文字版.pdf

    Linux C 编程一站式学习 宋劲杉 北京亚嵌教育研究中心 版权 © 2008, 2009 宋劲杉, 北京亚嵌教育研究中心 Permission is granted to copy, distri ...

  4. [转]《Python编程金典》读书笔记

    <Python编程金典>读书笔记 原文: http://man.chinaunix.net/develop/python/python_howto/python_howto_program ...

  5. 《Python编程金典》读书笔记

    << Back to man.ChinaUnix.net <Python编程金典>读书笔记 整理:Jims of 肥肥世家 <yjnet@21cn.com> 第一次 ...

  6. 《Java 并发编程实战》--读书笔记

    Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...

  7. 《javascript面向对象编程指南》读书笔记

    <javascript面向对象编程指南>读书笔记 <javascript面向对象编程指南>读书笔记 第一章 面向对象的JavaScript 第二章 基本数据类型与流程控制 变量 ...

  8. 《Java编程思想》读书笔记

    前言:三年之前就买了<Java编程思想>这本书,但是到现在为止都还没有好好看过这本书,这次希望能够坚持通读完整本书并整理好自己的读书笔记,上一篇文章是记录的第十七章到第十八章的内容,这一次 ...

  9. Core Java 8 读书笔记-Networking编程

    Core Java 8 读书笔记-Networking编程 作者:老九-技术大黍 原文:Core Java 8th Edition 社交:知乎 公众号:老九学堂(新人有惊喜) 特别声明:原创不易,未经 ...

最新文章

  1. 通向人工智能产业落地化的道路在哪?
  2. [HTML代码]会移动的文字(Marquee)
  3. 部署项目到阿里云服务器上遇到的问题
  4. 关于程序中的操作符左移和右移问题
  5. 语言教案 小小计算机,小班《小小手机本领大》语言教案
  6. 硬件基础:电脑当中各个硬件的作用介绍
  7. WildFly Kubernetes exec探针
  8. 关于云开发新服务“实时数据推送”,你需要了解的全在这了!
  9. 浙江使用计算机的用量,现在全世界计算机的使用量是多少
  10. python第三方库文件传输助手_Python中的第三方模块(itchat)
  11. 推荐一个看ELF文件的软件 010Editor
  12. for里面嵌套if_求求你们了,别再写满屏的 if/ else 了!
  13. 剑指offer 数字在排序数组中出现的次数
  14. eclipse jre 参数
  15. Repeater思路整理
  16. Mimics 21.0软件学习笔记(一)基本操作
  17. Deeping Learning for self-driving cars
  18. 工具学习——介绍几个C++项目可用的UML工具
  19. 关于小米8玩王者荣耀加载缓慢的情况
  20. Excel 去重找其他几列的最大值

热门文章

  1. Android 开发第四弹:围住神经猫(简单Demo)
  2. WebServiceHost 在ConsoleApplication中使用时添加命名空间添加不上,报错
  3. 函数作为变量,类型---golang
  4. Controller的要求
  5. php元素浮动会产生哪些影响,元素浮动的影响与三列布局的实现原理——2019年9月4日22时30分...
  6. 5G NR — 毫米波
  7. OpenvSwitch — 核心对象
  8. C 语言编程 — 高级数据类型 — 枚举
  9. NR 5G RLC无线链路控制
  10. 春节将至 香港推广“绿色年宵”呼吁惜物减废