您的位置:首页 > 理论基础 > 计算机网络

黑马程序员-网络编程(二)

2015-08-10 20:25 537 查看
——- android培训java培训、期待与您交流! ———-

1.1 TCP

1.1.1 文字发送 Demo

服务端:

package com.test.blog5;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ServerDemo {

public static void main(String[] args) throws IOException {
// 创建服务端对象
ServerSocket ss = new ServerSocket(10002);
// 获取连接过来的客户端对象。
Socket s = ss.accept();// 阻塞式
// String ip = s.getInetAddress().getHostAddress();
// 通过 socket 对象获取输入流,要读取客户端发来的数据。
InputStream in = s.getInputStream();

byte[] buf = new byte[24];

// int len = in.read(buf);
int len = 0;
// String text = new String(buf,0,len);
// System.out.println(ip + ":" + text);
StringBuilder sb = new StringBuilder();
while ((len = in.read(buf)) != -1) {
// sb.append(new String(buf, 0, len));
System.out.println("服务端接收到数据:" + new String(buf, 0, len));
}
s.close();
ss.close();
}
}


客户端:

package com.test.blog5;

import java.net.Socket;
import java.io.OutputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.io.InputStream;

public class ClientDemo {
public static void main(String[] args) throws UnknownHostException,
IOException {
// 创建客户端socket服务。
Socket socket = new Socket("127.0.0.1", 10002);
// 获取socket流中的输出流
OutputStream out = socket.getOutputStream();
// 使用输出流将指定的数据写出去。
out.write("TCP客户端发送数据".getBytes());

// 断开链接,关闭资源,socket获取的输出流也被关闭,没有必要再写代码关闭
socket.close();
}
}


启动服务端,然后启动客户端,运行结果:



1.1.2 交互Demo

发送端发送数据,服务端收到后返回数据

服务端:

package com.test.blog5;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ServerDemo {

public static void main(String[] args) throws IOException {
// 创建服务端对象
ServerSocket ss = new ServerSocket(10002);
// 获取连接过来的客户端对象。
Socket s = ss.accept();// 阻塞式
// String ip = s.getInetAddress().getHostAddress();
// 通过 socket 对象获取输入流,要读取客户端发来的数据。
InputStream in = s.getInputStream();

byte[] buf = new byte[24];

// int len = in.read(buf);
int len = 0;
// String text = new String(buf,0,len);
// System.out.println(ip + ":" + text);
// StringBuilder sb = new StringBuilder();
while ((len = in.read(buf)) != -1) {
// sb.append(new String(buf, 0, len));
System.out.println("服务端接收到数据:" + new String(buf, 0, len));
}
// 使用客户端socket对象的输出流给客户端返回数据
OutputStream out = s.getOutputStream();
out.write("收到".getBytes());
s.close();
ss.close();
}
}


客户端:

package com.test.blog5;

import java.net.Socket;
import java.io.OutputStream;
import java.io.IOException;
import java.net.UnknownHostException;
import java.io.InputStream;

public class ClientDemo {
public static void main(String[] args) throws UnknownHostException,
IOException {
// 创建客户端socket服务。
Socket socket = new Socket("127.0.0.1", 10002);
// 获取socket流中的输出流
OutputStream out = socket.getOutputStream();
// 使用输出流将指定的数据写出去。
out.write("TCP客户端发送数据".getBytes());
socket.shutdownOutput();// 重要,告诉服务端发送完毕
// 读取客户端返回的数据,使用Socket读取流。
InputStream in = socket.getInputStream();

byte[] buf = new byte[1024];

int len = in.read(buf);

String text = new String(buf, 0, len);

System.out.println(text);

// 断开链接,关闭资源,socket获取的输出流也被关闭,没有必要再写代码关闭
socket.close();
}
}


运行结果:





1.1.3 上传图片到服务器

服务端:

package com.test.blog5;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class PicUploadServer {
private static String pic = "d:" + File.separator + "pics";
private static String picType = ".jpg";

/*
* TCP--图片上传服务端
*/
public static void main(String[] args) {
try {
System.out.println("图片服务端启动成功-----------");
ServerSocket ss = new ServerSocket(10006);
Socket s = ss.accept();
// 接收图片的目录路径
File dir = new File(pic);
if (!dir.exists()) {
dir.mkdir();
}
// 定义接收客户端发送数据的流,注意是图片,不是文本数据,所以不用write类的包装
InputStream is = s.getInputStream();
// 定义往服务端存储文件的流
FileOutputStream fos = new FileOutputStream(new File(dir,
System.currentTimeMillis() + picType));

// 定义读取数据缓冲区
byte[] buf = new byte[1024];
int len = 0;
// 将数据写入
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
// 给客户端返回信息
PrintWriter pw = new PrintWriter(new OutputStreamWriter(
s.getOutputStream()), true);

pw.println("上传图片成功");

is.close();
fos.close();
s.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


客户端

package com.test.blog5;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class PicUploadClient {
/*
* TCP--图片上传客户端
*/
public static void main(String[] args) {
try {
System.out.println("图片客户端启动成功-----------");
Socket s = new Socket("127.0.0.1", 10006);
OutputStream os = s.getOutputStream();

File file = new File("d:\\3.jpg");
if (!file.exists()) {
throw new FileNotFoundException("文件不存在");
}
// 定义原始数据流
FileInputStream fis = new FileInputStream(file);
// 定义数据缓冲区
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
os.write(buf, 0, len);
}
s.shutdownOutput();// 重要,告诉服务端发送完毕,否则会出现死等现象
// 拿到客户端的读入流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 读取服务端返回信息
String result = br.readLine();
System.out.println("结果:" + result);

} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
}


运行结果:





1.1.4 上传文本到服务器

服务端:

package com.test.blog5;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadServer {
/*
* 上传文本文件服务端
*/
public static void main(String[] args) {
ServerSocket ss;
try {
System.out.println("服务端启动成功-----------");
ss = new ServerSocket(10005);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress() + "链接成功");
// 定义读取客户端发送数据的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 定义往服务端存数据的流
PrintWriter pw = new PrintWriter(new FileOutputStream(
"d:\\upload.txt"), true);
// 定义给客户端返回信息的流
PrintWriter out = new PrintWriter(s.getOutputStream(), true);

// 开始接收客户端信息并写入到服务端文件
String line = "";
while ((line = br.readLine()) != null) {
System.out.println(line);
pw.write(line + "\r\n");
pw.flush();
}
// 保存完毕给客户端返回信息
out.println("上传成功!");
br.close();
pw.close();
out.close();
s.close();
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}


客户端:

package com.test.blog5;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadClient {

/*
* 上传文本文件客户端
*/
public static void main(String[] args) {

try {
System.out.println("客户端启动成功-----------");
Socket s = new Socket("127.0.0.1", 10005);
// 定义读取源文件的流
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("d:\\out.txt")));
// 定义向服务端发送数据的流
PrintWriter out = new PrintWriter(new OutputStreamWriter(
s.getOutputStream()), true);
// 定义读取服务端返回信息的流
BufferedReader brin = new BufferedReader(new InputStreamReader(
s.getInputStream()));

String line = "";
while ((line = br.readLine()) != null) {
out.println(line);
}
//告诉服务端,客户端写完了,此步骤非常重要,不然服务端会阻塞一直在等待
s.shutdownOutput();
// 输出服务端返回的信息
System.out.println("服务端返回:" + brin.readLine());
br.close();
out.close();
s.close();

} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}


运行结果:



1.2 总结

****TCP传输流程:

**客户端:

建立Socket服务,并制定要连接的主机和端口;

获取Socket流中的输出流OutputStream,将数据写入流中,通过网络发送给服务端;

获取Socket流中的输出流InputStream,获取服务端的反馈信息;

关闭资源。

**服务端:

建立ServerSocket服务,并监听一个端口;

通过ServerSocket服务的accept方法,获取Socket服务对象;

使用客户端对象的读取流获取客户端发送过来的数据;

通过客户端对象的写入流反馈信息给客户端;

9738
关闭资源;

1.3 注意

Tcp连接方式必须先启动服务端后启动发送端

客户端告诉服务端发送完毕,避免双方阻塞死等现象。可以使用约定的结束符来判定,但是不是最好的方法,推荐使用socket.shutdownOutput();

同时处理多个客户端使用多线程

对于同一个socket,如果关闭了输出流,则与该输出流关联的socket也会被关闭。所以一般不用关闭流,直接关闭socket就可以了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息