Socket网络编程学习笔记

    大多数操作系统均使用系统调用(system call)的机制在应用程序和操纵系统之间传递控制权,网络编程亦是如此,网络中的进程是通过socket来进行通信的,那什么是socket呢?
    Socket,中文名套接字,起源于Unix,而Unix/Linux基本哲学之中的一个就是“一切皆文件”。都能够用“打开open –> 读写write/read –> 关闭close”模式来操作。
    笔者的理解,即Sockect就是网络编程中“应用进程与操作系统”之间的系统调用接口的集合,即应用进程与操作系统之间网络通信的中间件,如下图所示:
在这里插入图片描述
    通信过程如上图所示,当应用进程需要使用网络进行通信时,就会发出一种系统调用,请求操作系统为其建立“Socket套接字”,这样操作系统就会利用该模式下的中间件->Socket接口,将网络通信所需要的系统资源分配给该应用进程。这些资源的总和由Socket封装起来。

    通信完毕后,应用进行再通过一个关闭套接字的系统调用通知操作系统回收此Socket的所有资源。通信过程结束。

    Socket 的出现,使得程序员可以很方便的访问 TCP/IP,从而开发各种网络应用的程序

在 OSI 的各层所使用的协议:

1.应用层:Telnet,FTP,HTTP,DNS,SMTP,POP3
2.传输层:TCP,UDP
    TCP:面向连接的可靠的传输协议,通信前建立三次握手,握手成功后才能通信, 对数据准确性要求较高的场合使用,如从网上载的安装文件,不能缺少任何信息
    UDP:是无连接的,不可靠的传输协议,不需要建立连接,也没有重传和确认的机制,在实时性要求较高,但对数据准确度要求不是很高的场合使用,如视频会 议,在线观看电影,当中丢失个别数据包并不影响整体的效果。
3.网络层:IP

端口Port

    1.为了标识通信实体中进行通信的进程(应用程序),TCP/IP 协议提出了协议 端口的概念
    2.端口是一种抽象的软件结构(包括一些数据结构和 I/O 缓冲区)。应用程序 通过系统调用和某端口建立连接(binding)后,传输层传给该端口的数据都被 相应的进程所接收,相应进程发给传输层的数据都通过该端口输出
     3.端口用一个整数型标识符来表示,即端口号。端口号跟协议相关,TCP/IP 传 输层的两个协议 TCP 和 UDP 是完全独立的的两个软件模块,因此各自的端口号 也相互独立
     4.端口使用一个 16 位的数字来表示,它的范围是 0~65535,1024 以下的端 口号保留给预定义的服务,例如,http 使用 80 端

Socket系统调用顺序:

TCP连接在这里插入图片描述

UDP连接

在这里插入图片描述

基于TCP的Socket编程

Server端顺序:
1.加载套接字库
对于windows系统,加载“winsock.h ”,同时要链接其静态库“ws2_32.lib”,在调用Socket函数之前还要调用WSAStartup函数完毕对Winsock服务的初始化,如

#include "winsock2.h"
#pragma comment(lib, "Ws2_32.lib")

int main()
{
  WSADATA wdata;
  if ( WSAStartup(MAKEWORD(2,2), &wdata) !=0 )
  {
    return INVALID_SOCKET;
  }
...	
return 0;	
}

对于嵌入式系统,如用到lwip协议栈

#include <lwip/sys.h>
#include <lwip/sockets.h>

2.创建套接字(socket)

 SOCKET sServer; //服务器套接字
 sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

3.将套接字绑定到本地地址和端口上(bind)

//首先定义服务器地址参数
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(1234);
addrServ.sin_addr.S_un.S_addr = INADDR_ANY

//绑定套接字和服务器套接字地址
retVal = bind(sServer, (sockaddr*)&addrServ, sizeof(SOCKADDR_IN));

4.将套接字设为监听模式,准备接收客户请求(listen)

//开始监听,设置等待接受连接的队列长度
retVal = listen(sServer, 1);

5.等待客户请求的到来;当请求带来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)

//accept函数处于阻塞状态,直到接受了一个客户端请求。当该函数返回时,新建一个套接字,同时返回该客户端的地址
//如果调用失败,则返回INVALID_SOCKET
sClient = accept(sServer, (sockaddr*)&addrClient, &addrClientlen);

6.用返回的套接字和客户端进行通信(send/recv)

retVal = send(sClient, struct_buf, sizeof(struct_buf), 0);
retVal = recv(sClient, buf, sizeof(buf), 0);

7.返回,等待另一个客户请求
8.关闭套接字(closesocket)

客户端顺序:
1.加载套接字库
2.创建套接字(socket)
3.向服务器发送连接请求(connect)
4.和服务器端进行通信(send/receive)
5.关闭套接字(closesocket)

基于UDP的Socket编程

服务器端顺序:
1.加载套接字库
2.创建套接字(socket)
3.将套接字绑定到一个本地地址和端口上(bind)
4.等待接收数据(recvfrom)
5.关闭套接字(closesocket)

客户端顺序:
1.加载套接字库
2.创建套接字(socket)
3.向服务器发送数据(sendto)
4.关闭套接字(closesocket)

Socket各函数的详解

Socket各函数详解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值