详解 ServerSocket与Socket类
(请观看本人博文 —— 《详解 网络编程》)
ServerSocket与Socket
首先,本人来讲解下 ServerSocket 类:
ServerSocket 类:
概述:
这个类实现了服务器套接字
该类是遵循 TCP协议的,所以,必须要和客户端Socket建立连接,才能完成信息的接送
服务器套接字等待来自网络的请求。
它基于该请求执行某些操作,然后可能向请求者返回结果。
服务器套接字的实际工作由SocketImpl类的一个实例进行。
一个应用程序可以更改创建套接字实现的套接字工厂,
以配置自己创建适合本地防火墙的套接字
那么,本人再来展示下这个类的构造方法:
构造方法:
- ServerSocket()
创建一个绑定服务器套接字- ServerSocket(int port)
创建一个服务器套接字,绑定到指定的端口- ServerSocket(int port, int backlog)
创建一个服务器套接字,并将其绑定到指定的本地端口号,并使用指定的积压- ServerSocket(int port, int backlog, InetAddress bindAddr)
用指定的端口创建一个服务器,听积压,和本地IP地址绑定
现在,本人再来展示下这个类的API:
API:
- Socket accept()
监听要对这个套接字作出的连接并接受它- void bind(SocketAddress endpoint)
ServerSocket绑定到一个特定的地址(IP地址和端口号)- void bind(SocketAddress endpoint, int backlog)
ServerSocket绑定到一个特定的地址(IP地址和端口号)- void close()
关闭这个套接字。- ServerSocketChannel getChannel()
返回与此套接字关联的独特的 ServerSocketChannel对象,如果任何- InetAddress getInetAddress()
返回此服务器套接字的本地地址- int getLocalPort()
返回此套接字正在侦听的端口号- SocketAddress getLocalSocketAddress()
返回此套接字绑定到的端点的地址- int getReceiveBufferSize()
得到这个 ServerSocket的 SO_RCVBUF期权的价值,即该缓冲区的大小,将用于接受来自这 ServerSocket插座- boolean getReuseAddress()
如果 SO_REUSEADDR启用- int getSoTimeout()
检索设置 SO_TIMEOUT- protected void implAccept(Socket s)
子类使用此方法重载ServerSocket()返回自己的子类的插座- boolean isBound()
返回的ServerSocket绑定状态- boolean isClosed()
返回的ServerSocket关闭状态- void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
设置此ServerSocket性能偏好- void setReceiveBufferSize(int size)
设置一个默认值为提出接受这 ServerSocket插座 SO_RCVBUF选项- void setReuseAddress(boolean on)
启用/禁用 SO_REUSEADDR套接字选项- static void setSocketFactory(SocketImplFactory fac)
设置服务器套接字实现工厂为应用程序。- void setSoTimeout(int timeout)
启用/禁用 SO_TIMEOUT以指定的超时时间,以毫秒为单位- String toString()
返回此套接字作为 String实现的地址与端口
由于该类必须与Socket类对象建立连接后才能进行正常的网络通信,所以,本人在讲解完Socket类之后再来展示部分API的使用。
Socket类:
概述:
这个类实现了客户端套接字(也被称为“套接字”)
该类遵循TCP协议,所以必须与ServerSocket建立连接后,才能进行信息的接送
套接字是两台机器之间的通信的一个端点
套接字的实际工作是由该类的一个实例进行SocketImpl
一个应用程序,通过改变创建套接字实现的套接字工厂,可以配置自己创建适合本地防火墙的套接字
现在,本人来展示下这个类的构造方法:
构造方法:
- Socket()
创建一个连接的套接字,与socketimpl系统默认的类型。- Socket(InetAddress address, int port)
创建一个流套接字,并将其与指定的IP地址中的指定端口号连接起来。- Socket(InetAddress host, int port, boolean stream)
过时的。
使用UDP传输DatagramSocket。- Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
创建一个套接字,并将其与指定的远程端口上的指定的远程地址连接起来。- Socket(Proxy proxy)
创建一个连接的套接字类型,指定代理,如果有,应该使用无论任何其他设置。- protected Socket(SocketImpl impl)
创建一个用户指定的socketimpl连接插座。- Socket(String host, int port)
创建一个流套接字,并将其与指定的主机上的指定端口号连接起来。- Socket(String host, int port, boolean stream)
过时的。
使用UDP传输DatagramSocket。- Socket(String host, int port, InetAddress localAddr, int localPort)
创建一个套接字,并将其连接到指定的远程端口上的指定的远程主机上
那么,本人再来展示下这个类的API:
API:
- void bind(SocketAddress bindpoint)
将套接字绑定到本地地址。- void close()
关闭这个套接字。- void connect(SocketAddress endpoint)
将此套接字连接到服务器。- void connect(SocketAddress endpoint, int timeout)
将此套接字与指定的超时值连接到服务器。- SocketChannel getChannel()
返回与此套接字关联的独特的 SocketChannel对象,如果任何。- InetAddress getInetAddress()
返回套接字连接的地址。- InputStream getInputStream()
返回此套接字的输入流。- boolean getKeepAlive()
如果 SO_KEEPALIVE启用。- InetAddress getLocalAddress()
获取绑定的套接字的本地地址。- int getLocalPort()
返回此套接字绑定的本地端口号。- SocketAddress getLocalSocketAddress()
返回此套接字绑定到的端点的地址。- boolean getOOBInline()
如果 SO_OOBINLINE启用。- OutputStream getOutputStream()
返回此套接字的输出流。- int getPort()
返回此套接字连接的远程端口号。- int getReceiveBufferSize()
得到这个 Socket的 SO_RCVBUF选项的值,是由平台用于该 Socket输入缓冲区的大小。- SocketAddress getRemoteSocketAddress()
返回此套接字连接的端点的地址,或如果它是无关的 null。- boolean getReuseAddress()
如果 SO_REUSEADDR启用。- int getSendBufferSize()
得到这个 Socket的 SO_SNDBUF期权价值,即缓冲区的大小由平台用于输出在这 Socket。- int getSoLinger()
返回设置 SO_LINGER。- int getSoTimeout()
返回设置 SO_TIMEOUT。- boolean getTcpNoDelay()
如果 TCP_NODELAY启用。- int getTrafficClass()
获取从这个套接字发送的数据包的IP头中的业务类或服务类型- boolean isBound()
返回套接字的绑定状态。- boolean isClosed()
返回套接字的关闭状态。- boolean isConnected()
返回套接字的连接状态。- boolean isInputShutdown()
返回套接字连接的读半是否关闭。- boolean isOutputShutdown()
返回套接字连接的写是否关闭的是否关闭。- void sendUrgentData(int data)
在套接字上发送一个字节的紧急数据。- void setKeepAlive(boolean on)
启用/禁用 SO_KEEPALIVE。- void setOOBInline(boolean on)
启用/禁用 SO_OOBINLINE(TCP紧急数据收据)默认情况下,此选项是禁用TCP套接字上接收紧急数据是默默丢弃。- void setPerformancePreferences(int connectionTime, int latency, int bandwidth)
设置此套接字的性能首选项。- void setReceiveBufferSize(int size)
集 SO_RCVBUF选项,这 Socket指定值。- void setReuseAddress(boolean on)
启用/禁用 SO_REUSEADDR套接字选项。- void setSendBufferSize(int size)
设置这个 Socket指定值的 SO_SNDBUF选项。- static void setSocketImplFactory(SocketImplFactory fac)
设置客户端套接字实现工厂的应用程序。- void setSoLinger(boolean on, int linger)
启用/禁用 SO_LINGER与指定的逗留的时间秒。- void setSoTimeout(int timeout)
启用/禁用 SO_TIMEOUT以指定的超时时间,以毫秒为单位。- void setTcpNoDelay(boolean on)
启用/禁用 TCP_NODELAY(禁用/启用Nagle的算法)。- void setTrafficClass(int tc)
集交通类或从该套接字发送数据包的IP报头字节型服务。- void shutdownInput()
将此套接字的输入流放在“流结束”中。- void shutdownOutput()
禁用此套接字的输出流。- String toString()
将这一 String插座
那么,现在,本人来通过两个例子来展示下这两个类的使用:
例1:
题目:
这天右转哥玩游戏的时候,意外发现了游戏的一个Bug,于是,就向游戏公司发送信息,准备上报这个Bug
要求:
编写一个服务器端的代码,再编写一个客户端的代码,完成客户端向服务器端的Bug上报
那么,本人来展示下代码:
首先是服务器端的代码:
package edu.youzg.about_net.about_tcp.core;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(6666);
System.out.println("服务器已经开启,等待连接。。。");
Socket sk = ss.accept();
//循环读取客户端发来的消息
while (true){
InputStream in = sk.getInputStream();
String ip = sk.getInetAddress().getHostAddress();
byte[] bytes = new byte[1024];
int len = in.read(bytes);
String s = new String(bytes, 0, len);
if(s.equals("byebye")){
break;
}
System.out.println(ip+":给你发来消息内容是:"+s);
}
ss.close();
}
}
现在是客户端的代码:
package edu.youzg.about_net.about_tcp.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//客户端键盘录入服务器控制台输出
Socket sk = new Socket("localhost", 6666);
BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
while (true){
System.out.println("请输入消息");
String msg= bfr.readLine();
//发送给服务端
OutputStream out= sk.getOutputStream();
out.write(msg.getBytes());
if ("byebye".equals(msg)) {
break;
}
}
//释放资源
bfr.close();
}
}
那么,现在,本人再来展示下运行结果:
首先是客户端的控制台:

接下来是服务器端的控制台:

例2:
题目:
有一个壁纸很好康,右转哥的两个朋友十分想要,但是在网上找不到,朋友电脑上只有能运行Java程序的App,所以只能求右转哥想办法
要求:
通过网络编程所学知识,将目标图片传送至那两个朋友的电脑上
首先是 一个能够上传文件的线程实现类:
package edu.youzg.about_net.upload_file.core;
import java.io.*;
import java.net.Socket;
public class ServerThread extends Thread{
Socket sk;
public ServerThread(Socket sk) {
this.sk=sk;
}
@Override
public void run() {
try {
InputStream in = sk.getInputStream();
OutputStream out = sk.getOutputStream();
BufferedWriter bfw = new BufferedWriter(new FileWriter(System.currentTimeMillis() + "copyFile.txt")); //由于本人只有一台电脑,所以就将文件名跟事件相关
//包装一下输入流
BufferedReader bfr = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = bfr.readLine()) != null) {
bfw.write(line);
bfw.newLine();
bfw.flush();
}
//告诉客户端,文件上传成功
out.write("文件上传成功".getBytes());
bfw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
那么,本人先来展示下右转哥要运行的代码:
package edu.youzg.about_net.upload_file.core;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
public static void main(String[] args) throws IOException {
//服务器告诉浏览器上传成功了
ServerSocket ss = new ServerSocket(5555);
System.out.println("服务器已经开启。。。");
int i=1;
while (true){
Socket sk = ss.accept(); //侦听客户端
System.out.println((i++)+"个客户端已经连接");
//为每一个客户端,开启一个线程,去处理
new ServerThread(sk).start();
}
}
}
接下来,本人再来展示下两个朋友要运行的代码:
package edu.youzg.about_net.upload_file.core;
import java.io.*;
import java.net.Socket;
public class TCPClient {
public static void main(String[] args) throws IOException {
//给服务上传一个文本文件
Socket socket = new Socket("localhost", 5555);
//获取通道中的输入输出流
InputStream in= socket.getInputStream();
OutputStream out = socket.getOutputStream();
//读取文本文件
BufferedReader bfr = new BufferedReader(new FileReader("test.txt"));
String line=null;
//把通道中的输出流包装一下
BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(out));
while ((line=bfr.readLine())!=null){
bfw.write(line);
bfw.newLine();
bfw.flush();
}
//禁用此套接字的输出流。
socket.shutdownOutput();
//读取服务端反馈
byte[] bytes = new byte[1024];
int len = in.read(bytes);//阻塞式方法
String s = new String(bytes, 0, len);
System.out.println(s);
//释放资源
bfr.close();
socket.close();
}
}
那么,现在,本人来展示下运行结果:
首先,本人来展示下源文件的目录信息和源文件内容:

现在,本人来展示下运行后所生成的文件和该文件的内容:


那么,可以看到,我们将文件上传成功了!
(本人 网络编程 总集篇博文链接:https://www.cnblogs.com/codderYouzg/p/12419011.html)
详解 ServerSocket与Socket类的更多相关文章
- ServerSocket与Socket类
ServerSocket与Socket类 TCP套接字协议: TCP最主要的特征就是能够建立长时间的连接,而且能够保证数据安全的送达,但是速度比较慢.使用TCP进行连接的时候会有三次握手,之后才建立起 ...
- Android Studio 插件开发详解二:工具类
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112856 本文出自[赵彦军的博客] 在插件开发过程中,我们按照开发一个正式的项 ...
- 详解C++中基类与派生类的转换以及虚基类
很详细!转载链接 C++基类与派生类的转换在公用继承.私有继承和保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数和析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中 ...
- 详解 普通数组 —— Arrays类 与 浅克隆
我们在C语言中,编一些代码量规模比较大的程序,几乎都会用到 "数组" 或 "链表" ,但是,在本人之前的博文中,却对这两个知识点从未提到过,那么,本人将通过这篇 ...
- Java虚拟机详解(九)------类文件结构
我们知道计算机是由晶体管.电路板等组装而成的电子设备,而这些电子设备其实只能识别0与1的信号. 那么问题来了,我们在操作系统上编写的Java代码(由字母.数字等各种符号组成),打包后部署到服务器上,是 ...
- Linux 网络编程详解二(socket创建流程、多进程版)
netstat -na | grep " --查看TCP/IP协议连接状态 //socket编程提高版--服务器 #include <stdio.h> #include < ...
- Java中JNI的使用详解第二篇:JNIEnv类型和jobject类型的解释
上一篇说的是一个简单的应用,说明JNI是怎么工作的,这一篇主要来说一下,那个本地方法sayHello的参数的说明,以及其中方法的使用 首先来看一下C++中的sayHello方法的实现: JNIEXPO ...
- 详解 CSS 属性 - 伪类和伪元素的区别[转]
首先,阅读 w3c 对两者的定义: CSS 伪类用于向某些选择器添加特殊的效果. CSS 伪元素用于将特殊的效果添加到某些选择器. 可以明确两点,第一两者都与选择器相关,第二就是添加一些“特殊”的效果 ...
- spring mvc DispatcherServlet详解前传---HttpServletBean类
从上章里我们已经看到: DispatcherServlet extends FrameworkServlet FrameworkServlet extends HttpServletBean impl ...
随机推荐
- OSPF与ACL的综合应用
在企业中OSPF和ACL应用特别广泛,本实验介绍OSPF和ACL具体配置过程 实验拓扑: 实验要求: 1.企业内网运行OSPF路由协议,区域规划如图所示:2.财务和研发所在的区域不受其他区域链路不稳定 ...
- Windows下用Python你会几种copy文件的方法?
1. [代码]1. os.system ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import os import temp ...
- 学界!关于GAN的灵魂七问
根据一些指标显示,关于生成对抗网络(GAN)的研究在过去两年间取得了本质的进步.在图像合成模型实践中的进步快到几乎无法跟上. 但是,根据其他指标来看,实质性的改进还是较少.例如,在应如何评价生成对抗网 ...
- Consul+Nginx部署高可用
1. Consul Server 创建consul server虚拟主机 docker-machine create consul 出现如下内容即创建成功 Running pre-create che ...
- Python IDE ——Anaconda+PyCharm的安装与配置
一 前言 最近莫名其妙地想学习一下Python,想着利用业余时间学习一下机器学习(或许仅仅是脑子一热吧).借着研究生期间对于PyCharm安装的印象,在自己的电脑上重新又安装了一遍.利用周末的一点时间 ...
- 【强烈推荐】适合Flutter初学者的完整项目
简介 Flutter Fly是什么?Flutter Fly是一款开源的Flutter 项目,非常适合初学者进行学习.App内集成了160+Flutter基础控件的详细介绍及用法,内容来源于:http: ...
- hive的基本操作与应用
通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词 ...
- 牛客寒假基础集训营 | Day1 J题—u's的影响力(水题)
Day1 J题-u's的影响力 有一天,kotori发现了一个和lovelive相似的游戏:bangdream.令她惊讶的是,这个游戏和lovelive居然是同一个公司出的! kotori经过一段时间 ...
- Python魔法缓存,以数字开始
Python魔法缓存,以数字开始 众所周知,Python是弱类型的脚本语言,变量的定义是不用声明类型的. a = 1 Python所有数字的本质都是对象, 他们是不可改变的数据类型,这意味着改变数字数 ...
- 5个最佳WordPress通知栏插件
作者:品博客 链接:https://blog.pingbook.top/328/ 来源:品博客 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. WordPress通知栏可有效地将 ...