第1章 网络编程基础(2)——Socket编程原理

Socket编程原理

Socket是网络通信端点的一种抽象,它提供了一种发送和接收数据的机制。

  • 流socket(SOCK_STREAM):双向、有序、无重复、并且无记录边界
  • 数据报Socket(SOCK_DGRAM):双向、保留记录边界

面向连接的操作比无连接的操作效率低,但数据的安全性更高。

Socket通信流程

IP地址标志主机,端口号标志进程,IP加上端口号才能确定连接目标。

一个网络连接需要以下5种信息:

  1. 本地协议端口:指出接收报文或数据的进程。
  2. 本地主机地址:指出接收数据包的主机。
  3. 远程协议端口:指出目的进程或成。
  4. 远程主机地址:指出目的主机。
  5. 协议:指出程序在网络上传输数据时使用的协议。

Socket函数(Winsock)

1.Socket:用于创建一个Socket套接字。

SOCKET Socket(
int af,          //使用的协议族
int type,        //Socket类型
int protocol     //使用的协议地址
);

Socket协议族在计算机里表示为一个整数,可以取值AF_INET

Socket类型有两种:SOCK_STREAM和SOCK_DGRAM代表流Socket和数据报Socket

函数如果成功,返回一个Socket描述字,否则,返回INVALID_SOCKET。

SOCKET s = socket(AF_INET,SOCK_STREAM,0);

2.Connect:用于尝试与远端建立一个Socket连接。

int Connect(
SOCKET s,                          //socket描述符
const struct sockaddr* name,    //远端的地址
int namelen                        //远端地址的长度
);        

远端地址是一个SOCKADDR的结构

struct sockaddr_in(
short sin_family,                                 //socket族
u_short sin_port,                                 //端口
struct in_addr sin_addr,                          //IP地址
char sin_zero[8]                                  //结构长度
);                                    

函数如果连接成功,返回0,否则返回SOCKET_ERROR.对于非阻塞模式的Socket连接,返回结果通常是SOCKET_ERROR,并且错误代码为WSAEWOULDBLOCK,表示连接正在进行,而不是一个真正的错误。

建立连接通常是客户端发出连接请求:

SOCKET s;
SOCKADDR_IN ServerAddr;
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(Port);
ServerAddr.sin_addr.s_addr=inte_addr("127.0.0.1");
connect(s,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr));

3.Send:用于在某个Socket上向远端发送数据

int send(
SOCKET s,         //Socket套接字
const char* buf,     //存放发送数据的缓冲区
int len,          //将要发送的数据长度
int flags         //发送时使用的附加参数
);

如果发送成功,返回值为成功发送的字节数,否则返回SOCKET_ERROR。

4.Recv:与发送数据相对应的就是接收数据,函数Recv用于接收端发送的数据,函数原型为:

int recv(
SOCKET s,      //Socket套接字
char* buf,     //存放接收数据的缓冲区
int len,       //将要接收的数据长度
int flags      //接收时使用的附加参数
);

接收数据成功,函数返回接收的字节数,否则,返回SOCKET_ERROR。

5.Closesocket:用于关闭不再需要的Socket

int closesocket(
SOCKET s;        //socket套接字
);

关闭成功,返回0,否则返回SOCKET_ERROR。

6.Listen:用于在某个Socket上建立监听

int listen(
SOCKET s,      //Socket套接字
int backlog    //缓存队列的长度
);

如果建立监听成功,返回0;否则返回SOCKET_REEOR

backlog参数。设为SOMAXCONN,表示取系统连接的最大值。

7.Accept:用于接收一条新的连接。

SOCKET accept(

SOCKET s,//监听中的Socket

struct sockaddr* addr ,//表示地址结构体的指针

int* addrlen//地址结构体的长度

);

函数执行成功,返回0;否则,返回SOCKET_ERROR.

8.Bind:用于给一个Socket套接字分配一个本地协议地址

int bind(

SOCKET s,//Socket套接字

const struct socketaddr* name,//表示地址结构体的指针

int namelen//地址结构体的长度

);

函数执行成功,返回0;否则,返回SOCKET_ERROR.

9.Select:用于检测Socket状态,主要用于高级的网络通信模型

int select(

int nfds,//winsocj中此参数无意义

fd_set* readfds,//进行可读检测的Socket

fd_set* writefds,//进行可写检测的Socket

fd_set* exceptfds,//进行异常检测的Socket

const struct timeval* timeout//非阻塞模式中设置最大等待时间

);

函数执行成功,返回0;否则,返回SOCKET_ERROR.

IP地址转换

  • 无符号整数:127.0.0.1
  • ASCII地址:"127.0.0.1"
  • 域名:localhost

ASCII地址->整数地址

#include <arpa/inet.h>
int inet_aton(const char* straddr,struct in_addr* adrp);

返回:0表示转换不成功;1表示转换成功。

整数地址->ASCII地址

#include <arpa/inet.h>
char *inet_ntoa(struct in_addr inaddr);

返回:NULL编程转换不成功;其他返回值表示转换成功。

域名地址->整数地址

#include <netdb.h>
struct hostent *gethostname(const char *name);

整数地址->域名地址

#include <netdb.h>
struct hostent *gethostbyaddr(const char *addr,int len,int family);

字节转换

存储字节的格式:

  • 网路字节顺序:高字节在前(Big Endian)
  • 本机字节顺序:低字节在前(Little Endian)

函数命名规律:

h代表字节顺序(本机顺序),n代表网络顺序(network)

//本地字节转化为网络字节顺序(长整数)
u_long PASCAL FAR htonl(IN u_long hostlong);
//本地字节转化为网络字节顺序(短整数)
u_short PASCAL FAR htons(IN u_short hostshort);
//网络字节转化为本地字节顺序(长整数)
u_long PASCAL FAR ntohl(IN u_long netlong);
//网络字节转化为本地字节顺序(短整数)
u_short PASCAL FAR ntohs(IN u_short netshort);
时间: 2024-10-11 18:00:59

第1章 网络编程基础(2)——Socket编程原理的相关文章

从零开始学Python第八周:网络编程基础(socket)

Socket网络编程 一,Socket编程 (1)Socket方法介绍 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 套接字是一个双向的通信信道的端点.套接字可能在沟通过程,进程之间在同一台机器上,或在不同的计算机之间的进程 要创建一个套接字,必须使用Socket模块的socket.socket()方法 在socket模块中的一般语法: s = socket.

python基础之socket编程

python基础之socket编程   一 TCP/IP五层模型 在每一层都工作着不同的设备,比如我们常用的交换机就工作在数据链路层的,一般的路由器是工作在网络层的. 在每一层实现的协议也各不同,即每一层的服务也不同.下图列出了每层主要的协议. 各层功能 注明:ARP和RAPR两个到底属于哪一层呢? 由于IP协议使用了ARP协议,所以经常把ARP协议划到网络层,但是ARP协议是为了从网络层使用的IP地址解析出在数据链路层使用的MAC地址,所以有些地方也把ARP协议划分到数据链路层,但是一般情况下

Java笔记二十三.网络编程基础与UDP编程

网络编程基础与UDP编程 转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空) 一.网络编程基础 1.TCP/IP协议:TCP/IP协议是一个非常实用的网络应用程序通信协议,包括TCP(传输控制协议)和IP地址(计算机唯一标识号). 2.IP地址:IP在互联网中能唯一标识一台计算机,是每一台计算机的唯一标识(身份证),通过这个标识号来指定接收数据的计算机和识别发送数据的计算机,该标识号即为IP地址. (1)Ipv4:指在计算机中IP地址用4个字节(

网络编程基础之TCP编程学习(一)

网络编程基础了解 socket套接字 socket是一种通讯机制,它包含一整套的调用接口和数据结构的定义,他给应用程序提供了使用如TCP/UDP等网络通讯的手段. linux中的网络编程通过socket接口实现,socket既是一种特殊的IO,提供对应的文件描述符.一个完整的socket都有一个相关描述{协议,本地地址,本地端口,远程地址,远程端口};每个socket有一个本地唯一Socket,由操作系统分配. 定位某个计算机用IP,定位某个服务用端口. 创建Socket #include <s

Python 基础之socket编程(二)

Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 1. tcp的服务端 ss = socket() #创建服务器套接字 ss.bind() #把地址绑定到套接字 ss.listen() #监听链接 inf_loop: #服务器无限循环 cs = ss.accept() #接受客户端链接 comm_loop: #通讯循环 cs.recv()/cs.

Python 基础之socket编程(三)

python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友好的玩耍下去了.等等,又有一个用户来了,他呢也想和和服务端进行一下交流,于是他就给服务端发送了一条消息,之后等呀等不知过了多久,任然没有等到服务端给他发挥的消息,只有什么时候他就可以和服务端愉快的玩耍了呢?这个就需要第一个用户退出和服务器的链接,此时第二个客户端才会和服务端建立起链接,此时此刻,他才

iOS开发——网络编程OC篇&amp;Socket编程

Socket编程 一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象: 传输层.会话层.表示层和应用层则被称作主机层,是用户所面向和关心的内容. http协议   对应于应用层 tcp协议    对应于传输层 ip协议     对应于网络层 三者本质上没有可比性.  何况HTTP协议是基于TCP连接的. TCP/IP是传输层协议,主要

Python基础-第七天-面向对象编程进阶和Socket编程简介

本篇内容: 1.面向对象编程进阶-静态方法 2.面向对象编程进阶-类方法 3.面向对象编程进阶-属性方法 4.面向对象编程进阶-特殊成员(内置方法) 5.面向对象编程进阶-反射 6.异常处理.断言 7.Socket编程简介 一.面向对象编程进阶-静态方法 1.静态方法的实现 通过@staticmethod装饰器可以把其装饰的方法变为一个静态方法: 变成静态方法后,形参中可以不用写self了.如果写了self,默认是不会把对象本身传递给self,需要手动传递: class Dog(object):

网络 基于TCP协议socket编程

一.socket编程         1.socket编程        socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端号"唯一标识网络通讯中的一个进程,"IP地址+端口号"就称为socket.在TCP协议中,建立连接的两个进程各自有一个socket来标识,那么这两个socket组成 的socket pair就唯一标识一个连接. socket本义有"插座"的意思,因此用来描述网络连接的一对一关系.