怎样从一个接收到的socket数据流中读取一个整数出来
作者:百变鹏仔日期:2023-07-19 21:54:23浏览:14分类:文字大全
主要是你通过socket api封装要发送的数据,内部会自动封装成数据流进行传输。
1,什么是Socket
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
2,Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)
3,创建Socket
创建Socket
java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:
Socket(InetAddress address, int port);
Socket(InetAddress address, int port, boolean stream);
Socket(String host, int prot);
Socket(String host, int prot, boolean stream);
Socket(SocketImpl impl)
Socket(String host, int port, InetAddress localAddr, int localPort)
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
ServerSocket(int port);
ServerSocket(int port, int backlog);
ServerSocket(int port, int backlog, InetAddress bindAddr)
Socket client = new Socket("127.0.01.", 80);
ServerSocket server = new ServerSocket(80);
在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。
什么是Socket?
socket进行通信的方式如下:
使用socket()系统调用能够创建一个socket,它返回一个用来在后续系统调用中引用该socket的文件描述符。
socket存在于一个通信domain中,它确定:
现在操作系统支持下列domain:
每个socket实现都至少提供了两种socket:流和数据报。这两种类型在UNIX和Internet domain中都得到了支持。
流socket提供了一个可靠的双向的字节流通信信道:
数据报socket允许数据以数据报的形式进行交换。在使用时无需与另一个socket简历连接。
传入bind()的addr比较复杂,每种socket domain都使用了不同的地址格式,如UNIX domain socket使用路径名,而Internet domain socket 使用IP地址和端口号。struct sockaddr适用于所有domain,将各种domain特定的地址结构转换成单个类型以供socket系统调用中的各个参数使用。
socket I/O 可以使用传统的read()和write()系统调用或使用一组socket特有的系统调用send() recv() sendto() recvfrom()。默认情况下,这些系统调用在I/O操作无法被立即完成时阻塞,使用fcntl() F_SETFL 操作用启用 O_NONBLOCK 打开文件状态标记可以执行非阻塞I/O
listen()系统调用将文件描述符sockfd引用的流socket标记为被动,这个socket后面会被用来接受来自其他(主动的)socket的链接。
无法再一个已连接的socket(已成功执行connect()的socket或由accept()调用返回的socket)上执行 listen()
如果服务器正忙于处理其他客户端,那么客户端的connect()可能并不能马上被accept(),这将产生一个未决的连接。
内核必须要记录所有未决的连接请求的相关信息,backlog参数允许限制这种未决连接的数量。在这个限制之内的连接请求会立即成功,之外的连接请求就会阻塞直到一个未决的连接被接受,并从未决连接队列中删除。
accept()系统调用会文件描述符sockfd引用的监听流socket上接受一个连入连接。如果在调用accept时不存在未决的连接,那么调用会阻塞直到有连接请求到达为止。
返回的结果是已连接的socket的文件描述符。addr参数指向一个用来返回socket地址的结构。
一对连接的流 socket 在两个端点之间提供了一个双向通信信道。
关闭一个连接之后,对等应用程序读取数据时将会收到文件结束(所有缓冲数据都读取之后),如果要写入数据,会收到一个SIGPIPE信号,并且系统调用返回EPIPE错误。
无法保证顺序,也无法保证能够到达。由于底层协议有时会重新传包,也可能多次到达。
尽管数据报socket是无连接的,但在数据报socket上应用connect()系统调用仍然起作用,会导致内核记录这个socket的对等socket地址。
当一个数据报socket已连接后:
在UNIX domain中,socket地址以路径名来表示,domain特定的socket地址结构的定义如下:
为将一个UNIX domain socket绑定到一个地址上,需要初始化一个sockaddr_un结构,然后将指向这个结构的一个指针作为addr参数传入bind()并将addrlen指定为这个结构的大小。
当用来绑定UNIX domain socket时,bind()会在文件系统中创建一个条目,作为socket路径名的一部分的目录需要可访问和可写。这个文件会被标记为一个socket,当再这个路径名上应用stat()时,它会在stat结构的st_mode字段中的文件类型部分返回值S_IFSOCK。
尽管UNIX domain socket是通过路径名来标识的,但这些socket上发生的I/O无须对底层设备进行操作。
有关绑定一个UNIX domain socket的注意点:
服务器流程:
客户端流程:
对于UNIX domain socket来说,数据报的传输是在内核中发生的,也是可靠的,所有消息都会按序被递送并且不会发生重复的状况。
服务器创建socket后并绑定后,进入一个无线循环,在循环中使用recvfrom()接收来自客户端的数据报,将接收到的文本转换成大小格式并使用通过recvfrom()获取的地址将转换过的文本返回给客户端。
socket文件的所有权和权限决定了哪些进程能够与这个socket进行通信
有时候让单个进程创建一对socket并将它们连接起来是比较有用的。
允许将一个UNIX domain socket绑定到一个名字上但不会在文件系统中创建的名字
要传输数据,数据链路层需要将网络层传递过来的数据报封装进被称为帧的一个一个单元。最大传输单元MTC是改层所能传输的帧大小的上限。
网络层任务:
网络层的协议是IP,IPv4使用32位地址来标识子网和主机,IPv6则使用了128位的地址。
一个裸socket(SOCK_RAW),允许程序直接与IP层进行通信,但大多数都会基于一种传输层协议之上的socket。
IP以数据报(包)的形式来传输数据。在两个主机之间发送的每一个数据报都是在网络上独立传输的,它们经过的路径可能会不同。一个IP数据报包含一个头,其大小范围为20字节到60字节。包含目标主机的地址,源地址。
一个IP实现可能会给它所支持的数据报的大小设定一个上限。所有IP实现都必须做到数据报的大小上限至少与规定的IP最小重组缓冲区大小一样大。IPv4限制值是576字节,IPv6是1500字节。
IP是一种无连接协议,并没有在相互连接的两个主机之间提供一个虚拟电路。
IP是一种不可靠的协议:尽最大可能将数据报从发送者传输给接收者,但并不保证包到达的顺序与它们被传输的顺序一致,也不保证是否重复,甚至到达。IP也美誉错误恢复。可靠性是通过使用TCP来保证的。
IPv4为IP头提供了一个校验和,这样能够检测出头中的错误,但并没有为包中所传输的数据提供任何错误检测机制。IPv6并没有为IP头提供校验和,它依赖高层协议来完成错误检测和可靠性。
IP数据报的重复使可能发生的,数据链路层采用一些技术确保可靠性以及IP数据报可能会以隧道形式穿越采用了重传机制。
IP会将数据报分段成一个个大小合适的传输单元,这些分段在到达最终目的之后会被重组成原始的数据报(每个IP分段本身就包含一个偏移量)
什么是socket?
你经常听到人们谈论着“socket”,或许你还不知道它的确切含义。现在让我告诉你:它是使用标准Unix文件描述符(filedescriptor)和其它程序通讯的方式。什么?你也许听到一些Unix高手(hacker)这样说过:“呀,Unix中的一切就是文件!”那个家伙也许正在说到一个事实:Unix程序在执行任何形式的I/O的时候,程序是在读或者写一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数。但是(注意后面的话),这个文件可能是一个网络连接,FIFO,管道,终端,磁盘上的文件或者什么其它的东西。Unix中所有的东西就是文件!所以,你想和Internet上别的程序通讯的时候,你将要使用到文件描述符。你必须理解刚才的话。现在你脑海中或许冒出这样的念头:“那么我从哪里得到网络通讯的文件描述符呢?”,这个问题无论如何我都要回答:你利用系统调用socket(),它返回套接字描述符(socketdescriptor),然后你再通过它来进行send()和recv()调用。“但是...”,你可能有很大的疑惑,“如果它是个文件描述符,那么为什么不用一般调用read()和write()来进行套接字通讯?”简单的答案是:“你可以使用!”。详细的答案是:“你可以,但是使用send()和recv()让你更好的控制数据传输。”存在这样一个情况:在我们的世界上,有很多种套接字。有DARPAInternet地址(Internet套接字),本地节点的路径名(Unix套接字),CCITTX.25地址(你可以将X.25套接字完全忽略)。
鹏仔 微信 15129739599百科狗 baikegou.com
图片声明:本站部分配图来自网络。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!
- 上一篇:已经是第一篇了
- 下一篇:已经是最后一篇了
猜你还喜欢
- 05-15 侵组词有哪些词语
- 05-15 口字可以组成什么词呀
- 05-15 甚可以组什么词
- 05-15 海湾的湾怎样组词
- 05-15 桌字有什么组词?
- 05-15 诉字组词有哪些
- 05-15 模样的模怎么组词
- 05-15 转圈转的多音字是什么怎么组词多音字
- 05-15 pin第一声是什么字汉字
- 05-15 益字组词有哪些
- 05-15 周的周可以组什么词
- 05-15 飞机的飞字组词
- 搜索