Socket基础

127 阅读5分钟
本文系读书笔记,非深入研究,也无代码,如非所需,请见谅。

哦,这里有份不错的:Linux的SOCKET编程详解

[TOC]

1. 背景

花了好久的时间(大约一周,我太垃圾)看完了一篇英文文章:Bee'j Guide to Network Programming1。还有一本书:《TCP/IP Sockets in C - Practical Guide for Programmers》以及一份PPT:《Introduction to Sockets Programming in C using TCP/IP》,不过后二者没有看完就是了,也比较老,毕竟我要用的是IPv6,而非IPv4。【更新,现在说的那本书有了第二版,加入了IPv6的内容,中文翻译:TCP/IP Sockets编程(C语言实现)】 其实本科已经学过网络的书,网络最重要的不是ISO/OSI,而是TCP/IP,毕竟据老师所说,ISO/OSI是一群人喝醉酒想出来的,分别对应了7个小矮人2,最后还晚于事实标准TCP/IP,即便按照ISO/OSI的来了,还失败了,因为太复杂了。

2. 基础

Berkeley Sockets,一般简称为Sockets,是TCP/IP和应用程序之间的接口API,TCP/IP是OS的一个模块,是OS的一部分,应用程序通过系统调用来使用网络提供的服务和功能。应用程序通过Socket使用TCP/IP提供的服务,Socket就是TCP/IP的访问点。

从网络角度看,socket就是一个地址,有确定的IP和协议以及port,唯一标识TCP/IP网络中的一个结点。实际编程时,socket是一个动态的资源,通过socket()调用创建,系统返回一个socket对象的标识(或称指针)【Basil:其实是一unsigned int 类型32位整数】。在socket使用过程中,其占用的port口将只能被该应用程序使用。但是对于port,除非是由IANA分配过的,否则一般不是永久占用的,即用之后需要释放资源。

在TCP/IP中,一层层的抽象封装,下层对上层透明不可见,上层都是下层报文格式的数据部分,报头是一些控制信息。 TCP/IP Socket编程位于应用层之下、传输层之上。分为了Stream Socket和Datagram Socket,其实分别对应了传输层的两种协议,TCP和UDP。不过问题就来了,如果是DCTCP这种高级玩意是怎么搞得呢?以后再说吧。 还有C/S架构,其实两种架构:P2P以及C/S各有优缺点吧,不过本文只涉及C/S,B/S是C/S的一种特殊情况,P2P我还没有研究过。C/S架构就是类似下图: Client-Server Interaction 对了,作者是在*nix平台做的,Windows只是提了以下:Winsock.h

3. 流程

Socket编程的流程其实不复杂。 Socket Procedure 这样整个流程就出来了,就是先创建Socket,然后绑定(bind),其实connect()可以代替bind(),不过区别是,bind()绑定端口,而connect不关心使用哪个端口,当然是对传递的参数来说,connect()会帮程序员找一个未绑定端口进行绑定。服务器端监听对这个端口的连接请求,剩下的就是发送、接收数据了,这里注意Stream Socket(使用TCP连接)和Datagram Socket(使用UDP无连接)的发送和接收使用的函数是不同的。最后不要忘了关闭Socket。

PrimitiveMeaning
socket()创建socket
bind()指定本地地址,特别是为服务器socket指定具体的监听端口号
listen()监听连接
accept()服务器进程阻塞等待连接请求,在收到连接请求时建立连接
connect()客户机向服务器主动请求建立连接
send()发送数据
recv()接收数据
close()关闭和释放socket资源

其实剩下的主要是去看各个函数都需要哪些参数,怎么使用就好了,在文章的倒数第二章给了man pages,不贴了。理论上下面应该给出一个Client/Server的程序的,但是我觉着没什么必要。顺着我给的连接1过去就有很多,不贴了。 不过可以列一下使用了最多的头文件。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>  	
 	
#include <unistd.h>
#include <sys/socket.h>	
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

如果有时间,我学艺更精的时候再来补充。

3.1 TCP编程

TCP具有两类应用,一类是服务器Server,一类是客户端Client。服务器和客户端是请求响应模式,客户端主动发起请求,服务器被动响应。服务器的socket是被动打开的(passive open),客户端的socket是主动打开的。

TCP连接建立后,TCP能够在连续的双方向传送连续的8位字符流(continuous stream of octets in each direction)【Basil:存疑,不应该是字节流吗】。由于存在可能一次发送多个包,所以分包依据最好不要是接收语句;其次,为了充分利用TCP提供的稳定性和提高效率,不需要坚持每包发送-回应的做法。TCP连接由一对sockets唯一确定,可以用一个五元组描述:{TCP, Server IP, Server Port, Client IP, Client Port}。这样,服务器端地址相同,而客户机地址不同,还是可以区分不同连接,这样一个服务器端的Socket可以被多个客户端连接。这是并发服务器的实现基础。

建立TCP连接过程和并发服务器的工作原理

服务器IP地址:IP_A
客户机IP地址:IP_B
服务器端口:  21

+-----------------+    request for connection   +-----------------+
|     Server      | <-------------------------- |     Client1     |
+-----------------+                             +-----------------+
|     {TCP,A,21}------>listening                     {TCP,B,1500}
|            |generate
|            V 
|        +------------------+         connection1          +-----------------+
|        |Server SubRoutine1| <--------------------------> |    Client1      |
|        +------------------+                              +-----------------+
|             {TCP,A,21}------>connected                       {TCP,B,1500}
|generate
V 
+------------------+         connection2          +-----------------+
|Server SubRoutine2| <--------------------------> |    Client2      |
+------------------+                              +-----------------+
     {TCP,A,21}------>connected                       {TCP,B,1502}

参考

Footnotes

  1. Beej's Guide to Network Programming 2

  2. OSI模型究竟忽悠了多少人?