赞
踩
Java语言的基于套接字编程分为服务端编程和客户端编程,其通信模型如图所示:
客户端Socket的工作过程包含以下四个基本的步骤:
客户端创建Socket对象:
客户端程序可以使用Socket类创建对象,创建的同时会自动向服务器方发起连接,Socket的构造器是:
服务器程序的工作过程包含以下四个基本的步骤:
服务器建立 ServerSocket 对象:
ServerSocket 对象负责等待客户端请求建立套接字连接,类似邮局某个窗口中的业务员。也就是说,服务器必须事先建立一个等待客户请求建立套接字连接的ServerSocket对象。
所谓“接收”客户的套接字请求,就是accept()方法会返回一个 Socket 对象
这个我参考了其他博主的文章,我觉得写的非常清晰:
要求:客户端发送信息给服务端,服务端将数据显示在控制台上
代码实现:
//此为客户端
@Test
public void client() {
Socket kehu = null;
OutputStream words = null;
try {
//首先创建Socket(这个是指向服务器的)
kehu = new Socket("127.0.0.1",8989);
//开始传输信息
words = kehu.getOutputStream();
words.write("这里是客户端".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
}
//关闭流(使用try-catch)
if(words != null){
try {
words.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(kehu != null){
try {
kehu.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//此为服务端
@Test
public void server(){
ServerSocket receiver = null;
Socket receive = null;
InputStream shuru = null;
ByteArrayOutputStream box = null;
try {
//首先创建ServerSocket对相应端口进行监听
receiver = new ServerSocket(8989);
// 接收来自客户端的Socket
receive = receiver.accept();
//以此Socket创建输入流
shuru = receive.getInputStream();
//用ByteArrayOutputStream来接收,不建议使用byte型数组装然后再转为字符串,因为装满的时候
//正好有个字符的字节缺失
box = new ByteArrayOutputStream();
int len;
byte[] box1 = new byte[10];
while((len = shuru.read(box1)) != -1){
box.write(box1,0,len);
}
//将ByteArrayOutputStream缓冲区中的字节直接转化为字符串输出到控制台中
System.out.println(box.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
}
//关闭流
if(box != null){
try {
box.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (shuru != null){
try {
shuru.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(receive != null){
try {
receive.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(receiver != null){
try {
receiver.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注:①在服务器端不建议使用
//不建议这样写,可能会有乱码
// byte[] buffer = new byte[1024];
// int len;
// while((len = is.read(buffer)) != -1){
// String str = new String(buffer,0,len);
// System.out.print(str);
// }
②在服务器端使用了ByteArrayOutputStream的缓冲区去接收,而不是ByteArrayInputStream。
任务:客户端发送文件给服务端,服务端将文件保存在本地。
代码实现:
/*
这里涉及到的异常,应该使用try-catch-finally处理
*/
@Test
public void client() throws IOException {
//1.
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
//2.
OutputStream os = socket.getOutputStream();
//3.
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
//4.
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//5.
fis.close();
os.close();
socket.close();
}
/*
这里涉及到的异常,应该使用try-catch-finally处理
*/
@Test
public void server() throws IOException {
//1.
ServerSocket ss = new ServerSocket(9090);
//2.
Socket socket = ss.accept();
//3.
InputStream is = socket.getInputStream();
//4.
FileOutputStream fos = new FileOutputStream(new File("beauty1.jpg"));
//5.
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
//6.
fos.close();
is.close();
socket.close();
ss.close();
}
任务:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。
代码实现:
/*
这里涉及到的异常,应该使用try-catch-finally处理
*/
@Test
public void client() throws IOException {
//1.
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
//2.
OutputStream os = socket.getOutputStream();
//3.
FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
//4.
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
os.write(buffer,0,len);
}
//关闭数据的输出
socket.shutdownOutput();
//5.接收来自于服务器端的数据,并显示到控制台上
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[20];
int len1;
while((len1 = is.read(buffer)) != -1){
baos.write(buffer,0,len1);
}
System.out.println(baos.toString());
//6.
fis.close();
os.close();
socket.close();
baos.close();
}
/*
这里涉及到的异常,应该使用try-catch-finally处理
*/
@Test
public void server() throws IOException {
//1.
ServerSocket ss = new ServerSocket(9090);
//2.
Socket socket = ss.accept();
//3.
InputStream is = socket.getInputStream();
//4.
FileOutputStream fos = new FileOutputStream(new File("beauty2.jpg"));
//5.
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
fos.write(buffer,0,len);
}
System.out.println("图片传输完成");
//6.服务器端给予客户端反馈
OutputStream os = socket.getOutputStream();
os.write("你好,照片我已收到".getBytes());
//7.
fos.close();
is.close();
socket.close();
ss.close();
os.close();
}
注意:客户端传完图片之后一定要关闭数据的输出(shutdownOutput()),如果不手动关闭,因为服务端接收时的read()方法是一种阻塞式的方法,他会一直等到客户端传输结束,但是这个信号一直没有来,他就会一直等。((len = is.read(buffer)) != -1并不能阻止这个情况的发生,因为read返回-1是代表到达流的末尾,而此时read是不能确定是否到达了流的末尾的,所以他才一直等)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。