简单介绍Socket通信及所用到的函数

Socket通信过程

                 

       (嘘~,偷来的图)

客户端

  1. 调用socket()函数创建套接字
  2. 调用connect()函数连接服务端
  3. 调用write()/read()函数和send()/recv()函数进行数据的收发
  4. 调用close()函数关闭socket

服务器端

  1. 调用socket()函数创建套接字,再用bind()函数将创建的套接字与服务器端IP地址绑定
  2. 调用listen()函数监听socket()函数创建的套接字,等待客户端的连接请求
  3. 调用accept()函数接收连接请求,返回一个对应于此连接的新的套接字,用于通信
  4. 调用write()/read()函数和send()/recv()函数进行数据的读写,通过accept()函数返回的套接字和客户端进行通信
  5. 调用close()函数关闭socket

Socket 函数介绍

socket()

int socket(int domain, int type, int protocol);

描述:用于创建一个套接字描述符。

返回值:成功时返回一个全新的文件描述符,失败时返回-1。

参数:

  1. domain: 即协议域,又称为协议族(family),默认选择AF_INET 

类型

说明

AF_INET

IPv4网络通信

AF_INET6

IPv6网络通信

AF_PACKET

链路层通信

AF_UNIX, AF_LOCAL

本地通信

      2. type:数据传输方式/套接字类型

类型

说明

SOCK_STREAM

字节流套接字

SOCK_DGRAM

数据报套接字

SOCK_SEQPACKET

有序分组套接字

SOCK_RAW

原始套接字

     3. type:表示传输协议,可设置为0,表示选择当前family和type组合下的系统  默认值

类型

说明

IPPROTO_TCP

TCP传输协议

IPPTOTO_UDP

UDP传输协议

IPPROTO_SCTP

STCP传输协议

IPPROTO_TIPCTCP

TIPC传输协议

注意:参数中type和protocol并不能随意组合。

bind()

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

描述:用于服务器端,为套接字绑定网络地址和端口号。可以理解为我们调用一个socket()创建一个socket时,返回的socket描述字存在于协议族空间中,但没有具体的地址。如果想要给它一个地址,就需要调用bind()函数。如果只想使用connect()则不需要调用,因为当使用connect()函数调用,它会检查socket是否已经绑定,如果没有,它会分配一个空闲的端口。

返回值:成功返回0,否则返回-1,并设置错误码。

参数:

  1. sockfd:需要绑定的套接字文件描述符,由socket()函数创建的,唯一标识一个socket
  2. addr:指向特定协议的地址结构的指针,地址结构根据地址创建socket时的地址协议族不同而不同
  3. addrlen:对应的地址长度

listen()

int listen(int sockfd, int backlog);

描述:将一个套接字描述符设为监听套接字(主动转为被动描述符),使其能够自动接收到来的连接,并为连接队列指定一个长度限制。

返回值:成功返回0,否则返回-1,并设置错误码。

参数:

  1. sockfd:需要绑定的套接字文件描述符,由socket()函数创建的,唯一标识一个socket
  2. backlog:设置连接队列的长度

补充:backlog参数详解

https://blog.csdn.net/ordeder/article/details/21551567?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7Eessearch%7Evector-13.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7Eessearch%7Evector-13.essearch_pc_relevant

connect()

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

描述:让目标套接字与指定的网络地址和端口号连接。

返回值:成功返回0,否则返回-1,并设置错误码。

参数:

  1. sockfd:需要绑定的套接字文件描述符,由socket()函数创建的,唯一标识一个socket
  2. addr:指向特定协议的地址结构的指针,地址结构根据地址创建socket时的地址协议族不同而不同(一般是服务器端的协议地址)
  3. addrlen:对应的地址长度

accept()

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

描述:被动监听客户端发起的tcp连接请求,三次握手后连接建立成功。

返回值:成功返回一个套接字文件描述符,专门用于与连接成功的客户端进行通信。否则返回-1,并设置错误码。

参数:

  1. sockfd:需要绑定的套接字文件描述符,由socket()函数创建的,唯一标识一个socket
  2. addr:指向特定协议的地址结构的指针,地址结构根据地址创建socket时的地址协议族不同而不同(一般是客户端的协议地址)
  3. addrlen:对应的地址长度

write()

#include<unistd.h>

ssize_t write(int fd,const void*buf,size_t count);

描述:用于往文件描述符对应的buffer写数据。

返回值:成功返回写入的字节数,否则返回-1,并设置错误码。

参数:

  1. fd:accept()函数返回的用于连接套接字文字描述符
  2. buf:待发送的数据的缓冲区
  3. count:缓冲区大小

read()

#include<unistd.h>

ssize_t write(int fd,const void*buf,size_t count);

描述:用于从文件描述符对应的buffer读取数据。

返回值:成功返回读出的字节数,否则返回-1,并设置错误码。

参数:

  1. fd:accept()函数返回的用于连接套接字文字描述符
  2. buf:接受到的数据的缓冲区
  3. count:缓冲区长度

send()

ssize_t send(int sockfd, const void *buf, size_t len, int flags)

描述:向tcp连接的另一端发送数据。

返回值:成功时返回发送的字符数,否则返回-1,并设置错误码。

参数:

  1. sockfd:accept()函数返回的用于连接套接字文字描述符
  2. buf:待发送的数据的缓冲区
  3. len:缓冲区长度
  4. flags:调用方式标志位,一般为0,改变flags将改变send发送的形式

recv()

ssize_t recv(int sockfd, void *buf, size_t len, int flags)

描述:从tcp连接的另一端接收数据。

返回值:成功时返回接收的字符数,否则返回-1,并设置错误码。

参数:

  1. sockfd:accept()函数返回的用于连接套接字文字描述符
  2. buf:接受到的数据的缓冲区
  3. len:缓冲区长度
  4. flags:调用方式标志位,一般为0,改变flags将改变recv接收的形式

类型

说明

MSG_DONTROUTE

不查找表

MSG_OOB 

接受或者发送带外数据

MSG_PEEK 

表示只是从系统缓冲区中读取内容,而不清除系统缓冲区的内容

MSG_WAITALL

表示等到所有的信息到达时才返回

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Winsock程序设计初步之 Winsock编程原理     本课程主要讲Windows中TCP/IP编程接口Winsock,版本为1.1。高版本的Winsock实际与1.1版相差不多,主要是进行了一些扩充,如可超越TCP/IP协议直接用socket来实现IPX、NETBIOS等其它通信协议。   这叙述方便在本文的其余部分中提到的Winsock指的就是Winsock1.1。   通过Winsock可实现点对点或广播通信程序,实际这两者之间的区别不大,编程时其程序流程所用代码几乎相同,不同的地方在于目标地址选择的不同。本课程中所举实例为点对点的形式,并以客户/服务器形式来构建通过Winsock进行通信的点对点通信,并对通信过程的两点分别命名为Server和Client。 为更清楚的说明出Winsock的结构原理,下面以电信局的普通电话服务为比较对象进行说明: 1、电信局提供电话服务类似版主们这的Server,普通电话用户类似版主们这的Client。 2、首先电信局必须建立一个电话总机。这就如果版主们必须在Server端建立一个Socket(套接字),这一步通过调用socket()函数实现。 3、电信局必须给电话总机分配一个号码,以便使用户要拨找该号码得到电话服务,同时接入该电信局的用户必须知道该总机的号码。同样,版主也在Server端也要为这一套接字指定一port(端口),并且要连接该Server的Client必须知道该端口。这一步通过调用bind()函数实现。 4、接下来电信局必须使总机开通并使总机能够高效地监听用户拨号,如果电信局所提供服务的用户数太多,你会发现拨打电信局总机老是忙音,通常电信局内部会使该总机对应的电话号码连到好几个负责交换的处理中心,在一个处理中心忙于处理当前的某个用户时,新到用户可自动转到一下处理中心得到服务。同样版主们的Server端也要使自己的套接口设置成监听状态,这是通用listen()函数实现的,listen()的第二个参数是等待队列数,就如同你可以指定电信局的建立几个负责交换的处理中心。 5、用户知道了电信局的总机号后就可以进行拨打请求得到服务。在Winsock的世界里做为Client端是要先用socket()函数建立一个套接字,然后调connect()函数进行连接。当然和电话一样,如果等待队列数满了、与Server的线路不通或是Server没有提供此项服务时,连接就不会成功。 5、电信局的总机接受了这用户拨打的电话后负责接通用户的线路,而总机本身则再回到等待的状态。Server也是一样,调用accept()函数进入监听处理过程,Server端的代码即在中处暂停,一旦Server端接到申请后系统会建立一个新的套接字来对此连接做服务,而原先的套接字则再回到监听等待的状态。 6、当你电话挂完了,你就可以挂上电话,彼此间也就离线了。Client和Server间的套接字的关闭也是如此;这个关闭离线的动作,可由Client端或Server端劝嬷骰方先关闭。有些电话查询系统不也是如此吗?关闭套接字的函数为 closesocket()。 从以上情况可以看出在服务器端建立一个套接字,并进入实际的监听步骤的过程如下:socket()->bind()->listen()->accept() 那么在accept()完了后,版主们说在Server端将生成一个新的套接字,然后Server将继续进入accept()状态,版主们该如何用这个新的套接字来进行与Client端的通信呢,这就用到了recv()函数,而Client端则是通过send()函数来向服务器发信息的。
实验三Socket通信实验报告 (1)实验目的和要求 1. 掌握VB、VC++、VS或JAVA等集成开发环境编写网络程序的方法; 2. 掌握客户/服务器(C/S)应用的工作方式; 3. 学习网络中进程之间通信的原理和实现方法; 4. 理解单播、组播和广播的原理并比较其不同之处; 5. 要求本机既是客户端又是服务器端; (2)实验内容 所编写的程序应具有如下功能: 1. 具有点对点通信功能,任意客户端之间能够发送消息; 2. 具有群组通信功能,客户端能够向组内成员同时发送消息,其他组成员不能收到; 3. 具有广播功能,客户端能够向所有其他成员广播消息; (3)编程语言和环境 1. 编程语言C/C++/C#/Java等均可; 2. 编程环境Windows(MS Visual系列,VC/VB/VS.Net;)和Linux(编辑器vi+编译器GCC)均可; (4)实验主要功能实现说明 以下为针对三个实验内容实现方法的简要说明,示例所用语言为C。 基于C的面向连接的socket编程模型 1. 点对点通信功能 实现网络点对点通讯程序的关键步骤就是实现信息在网络中的发送和接收。数据接收 使用的是Socket,数据发送使用的是NetworkStream。 1.1利用Socket来接收信息 TcpListener tlListen1 = new TcpListener ( 8889 ) ; //侦听端口号 tlListen1.Start ( ) ; Socket skSocket = tlListen1.AcceptSocket ( ) ; //接受远程计算机的连接请求,并获得用以接收数据的Socket实例 EndPoint tempRemoteEP = skSocket.RemoteEndPoint ; //获得远程计算机对应的网络远程终结点 while ( true ) { Byte [] byStream = new Byte[80] ; //定义从远程计算机接收到数据存放的数据缓冲区 int i = skSocket.ReceiveFrom ( byStream , ref tempRemoteEP ) ; //接收数据,并存放到定义的缓冲区中 string sMessage = System.Text.Encoding.UTF8.GetString ( byStream ) ; //以指定的编码,从缓冲区中解析出内容 MessageBox.Show ( sMessage ) ; //显示传送来的数据 } 1.2利用NetworkStream来传送信息 TcpClient tcpc = new TcpClient ( "10.138.198.213" , 8888 ) ; //对IP地址为"10.138.198.213"的计算机的8888端口提出连接申请 NetworkStream tcpStream = tcpc.GetStream ( ) ; //如果连接申请建立,则获得用以传送数据的数据流 string sMsg = "您好,见到您很高兴" ; StreamWriter reqStreamW = new StreamWriter ( tcpStream ) ; //以特定的编码往向数据流中写入数据 ,默认为UTF8编码 reqStreamW.Write ( sMsg ) ; //将字符串写入数据流中 reqStreamW.Flush ( ) ; //清理当前编写器的所有缓冲区,并使所有缓冲数据写入基础流 2. 群组通信功能 组播编程需要UDP,有两个类支持组播网络编程Socket和UdpClient.一台计算机要加 入某一个组,然后接收发往这个组的信息。Socket类要调用SetSocketOption函数加入和 离开某一个组。UdpClient类有直接的加入和离开某个组的成员函数可以调用。而向某个 组发信息,则没有什么特殊的,只需把发送数据的目的地址设为组播地址就可以了。 发送端: Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint iep = new IPEndPoint(IPAddress.Parse("224.0.0.1"), 3000); EndPoint ep = (EndPoint)iep; byte[] b = Encoding.ASCII.GetBytes("just a test!"); s.SendTo(b, ep); s.Close(); 接收端: Socket s = new Socket(AddressFamily.InterNetwork, SocketTyp
课程名称 计算机网络 实验序号 实验五 实验项目 Ping程序的设计与实现 2017年 03月 25 日 实验报告要求 1、实验报告封面填表说明(每份实验报告必须附上封面) (1)课程名称:要求与实验大纲和实验指导书中的课程名称一致。 (2)实验序号:指该课程的第几个实验。 (3)实验项目:要求与实验大纲和实验指导书中的实验项目一致。 (4)实验地点:填写完成该实验项目所在的实验室名称。 (5)实验学时:要求与实验大纲和实验指导书中完成该实验项目所需学时一致。 (6)实验类型:是指演示性、操作性、验证性、综合性、设计性。 演示性:教师操作,学生观察,验证理论、说明原理和方法。 操作性:学生按要求动手拆装、调试实验装置或上机操作,掌握其基本原理和方法。 验证性:按实验指导书(教材)要求,由学生通过操作验证所学理论,加深对理论、 知识的理解,掌握基本实验知识、方法、技能、数据处理等。 综合性:实验容涉及本课程的综合知识或相关课程的知识,运用多的知识、多种方法 ,按要求或自拟实验方案进行实验。主要培养学生综合运用所学知识、实验方法和实验 技能,以培养其分析、解决问题的能力。 设计性:给定实验目的、要求和实验条件,学生自己设计实验方案并加以实现的实验 。学生独立完成从查阅资料、拟定实验方案、实验方法和步骤(或系统分析和设计)、 选择仪器设备(或自行设计缺制作)进行实验并完成实验全过程,形成实验报告,培养 学生自主实验的能力。 2、实验报告的格式 "软件类实验报告格式"公共课实验报告"硬件类实验报告格式 " " "格式 " " "序 "要求 "序"要求 "序"要求 " "号 " "号" "号" " "1 "实验目的及要求"1 "实验目的及 "1 "实验预习 "实验目的实验原理及容(简" " " " "要求 " " "明扼要,主要是实验接线图" " " " " " " ") " "2 "实验原理与容 "2 "实验步骤 " " "所用仪器设备 " "3 "实验软硬件环境"3 "操作要点 " " "预习思考题 " "4 "实验过程(实验"4 "实验结果 "2 "实验原始 "画出实验所需要的各种记录" " "步骤、记录、数" " " "记录(经 "表格 " " "据、分析) " " " "实验指导 " " " " " " " "教师签名 " " " " " " " "认可) " " "5 "测试/调试及实 "5 "实验问题 "3 "实验报告 "数据处理(数据表格、计算" " "验结果分析 " " " " "结果、误差、结果表达、曲" " " " " " " "线图等) " "6 "实验结论与体会"6 "小结及讨论 " " "结论 " " " " " " " "讨论 " 3、教师批改学生实验报告要求 (1)批改:全部批改及更正错误。 (2)评分:按百分制评分,不能评分为"优、良、中、差"或"A、B、C"。 (3)签名及批改日期:任课教师必须在每份学生实验报告中签名和写上批改日期。 (4)成绩:填写学生实验成绩表,实验成绩作为考试成绩评定的依据。 (4)评语:任课教师批改学生实验报告时,应给出简明扼要的评语。 "成绩: " "教" " "师" " "评" " "语" " " "指导教师签名: 批阅日期: " "一、实验目的及要求 " " " "加深对ICMP协议的理解 " "熟悉原始套接字的使用方法 " "掌握PING程序的实现流程 " " " " " "二、实验原理与容 " " " "一种网络诊断工具 " "发送ICMP回送请求报文 " "接收 ICMP回送应答报文 " " " "IP报文格式 " " " "WinSock原始套接字的使用方法与API函数 " "Winsock原始套接字编程过程中,服务器端/客户端的编程都按照以下步骤: " "初始化套接字(WSAStartup) " "创建套接字(socket或WSASocket) " "向服务器通信(sendto/recvfrom) " "关闭套接字(closesocket) " "结束使用套接字(WSACleanup) " " " " " "三种WinSock地址结构 " "用的Winsock地址结构sockaddr " ",针对各种通信域的套接字,存储它们的地址信息。 " "专门针对Internet 通信域的Winsock地址结构sockaddr_in " "专用于存储IP地址的结构in_addr " " " "三、实验软硬件环境 " " " "运行Windows XP/ Windows Server 2003/Windows 7操作系统的PC一台 " "Visual C++6.0/ Visual Studio 2005/Visual Studio 2010开发环境 " " " "四、实验

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值