一、客户端相关内容
1、客户端的程序使用Socket类建立与服务器的套接字连接。向服务器端发出连接请求
由于在使用Socket构造方法创建Socket对象时会产生IOException异常,所以在创建Socket对象时应处理IOException异常
如:
try{
Socket socket=new Socket(http://www.gduf.edu.cn,1880);
}catch(IOException e){
}
2、getInputStream()方法 读取服务器放入线路中的信息
Socket对象socket可以使用getInputStream()方法获得输入流,利用这个输入流读取服务器放入线路中的信息
如:
BufferedReader cin=new BufferedReader(new InputStreamReader(socket.getInputStream()));
3、getOutputStream()方法 将数据写入线路
如:
PrintStream cout=new PrintStream(socket.getOutputStream());
或
DateOutputStream cout=new DateOutputStream(socket.getInputStream());
二、服务器端相关内容
1、服务器端的程序使用ServerSocket类建立一个等待接收客户套接字的服务器套接字。
同样在使用ServerSocket构造方法创建ServerSocket对象时也会产生IOException异常,所以在创建ServerSocket对象时也应处理IOException异常
如:
try{
ServerSocket serSocket=new ServerSocket(1880);
}catch(IOException e){
}
2、accept()方法 接收客户的套接字mySocket 等待连接
try{
Socket sc=serSocket.accept();
}catch(IOException e){
}
将收到的客户端的mySocket放到一个已经声明的Socket对象 sc中。
3、getOutputStream()方法 服务器端向线路写信息,发送到线路端
将收到的客户端的mySocket放到一个已经声明的Socket对象 sc中。这样服务器的sc就可以使用getOutputStream()方法获得输出流,然后用这个输出流向线路写信息,发送到客户端
BufferedReader sin=new BufferedReader(new InputStreamReader(socket.getInputStream()));
4、getInputStream()方法 读取客户放入线路中的信息
服务器的sc可以使用getInputStream()方法获得输入流,然后用这个输入流读取客户放入线路的信息
PrintStream sout=new PrintStream(socket.getOutputStream());
或
DateOutputStream sout=new DateOutputStream(socket.getInputStream());
三、Socket通信的步骤如下:
(1)在服务器端创建一个ServerSocket对象,并指明端口号
(2)运行ServerSocket的accept()方法,等候客户端请求
(3)客户端创建一个Socket对象,指定服务器的IP地址和端口号,向服务器端发出连接请求
(4)服务器端接收到客户端请求后,创建Socket对象与客户端建立联系
(5)服务器端和客户端分别建立输入输出数据流,进行数据传输
(6)通信结束后,服务器端和客户端分别关闭相应的Socket连接
(7)服务器端程序运行结束后,调用ServerSocket对象的close()方法停止等候客户端请求
四、实际应用
1、实现客户端向服务器器端上传图片
class Client{
public static void main(String[] args) throws IOException {
//连接服务器 获取socket
Socket socket = new Socket("127.0.0.1",8080);
//创建服务器端对应的输入流 用于接收服务器端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(br.readLine());
//向服务器端发送文件(图片)
//1.将文件写入到内存里
String path = "C:\\Users\\17153\\Desktop\\F.jpg";
FileInputStream fis = new FileInputStream(path);
//2.创建字节流 outputStream
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[1024];
int len = -1;
while ((len = fis.read(buf)) != -1){
bos.write(buf,0,len);
}
socket.shutdownOutput();
}
}
class Server{
public static void main(String[] args) throws IOException {
//创建服务器端的ServerSoket
ServerSocket ss = new ServerSocket(8080);
//监听客户端连接
//当有客户端来连接这个服务器 就可以得到对应的socket
//当没有客户端来连接 服务器一直在这里等待
Socket socket = ss.accept();
//创建客户端对应的输出流 用于向这个客户端发送数据
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println("连接成功 可以发数据了!");
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
String path = "D:\\android studio java\\lib1\\src\\main\\java\\swu\\syq\\lib6\\lib5\\1.jpg";
FileOutputStream fos = new FileOutputStream(path);
byte[] buf = new byte[1024];
int len = -1;
while((len = bis.read(buf)) != -1){
fos.write(buf,0,len);
}
}
}
2、(使用多线程)对聊
//模拟客户端
class Client{
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.2.205",8000);
//子线程 处理服务端数据
new Thread(new ClientThread(socket)).start();
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//客户端的输出流对象
PrintStream printStream = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine())!= null){
printStream.println(line);
}
}
}
创建一个子线程 给客户端用于处理、接收服务器端的数据
class ClientThread implements Runnable{
private Socket socket;
//保存操作的socket 对象
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
//获取输入
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//读取
String line = null;
while ((line=bufferedReader.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络出错 请重新登录");
System.exit(-1);
}finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (socket != null) {
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
//模拟服务器端
class Server{
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8000);
Socket socket = serverSocket.accept();
new ServerThread(socket).start();
//终端输入流对象
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//客户端的输出流对象
PrintStream printStream = new PrintStream(socket.getOutputStream());
//读取终端的输入 输出给客户端
String line = null;
while ((line = keyin.readLine())!= null){
printStream.println(line);
}
}
}
//创建一个子线程 给服务器端用于处理、接收客户端的数据
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
bufferedReader= new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络异常 请重新登录");
}finally {
try{
if(bufferedReader != null){
bufferedReader.close();
}
if (socket!= null){
socket.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}
3、群聊
和对聊只是Server类的区别 需要一个数组来保存所有客户端 发消息的时候是群发用遍历来实现
class Server{
public static ArrayList<Socket> sockets = new ArrayList<>();
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8000);
while (true){
Socket socket = serverSocket.accept();
//当客户连接过来就保存
sockets.add(socket);
new ServerThread(socket).start();
}
}
}
class Client{
public static void main(String[] args) throws IOException {
Socket socket = new Socket("10.129.2.205",8000);
//子线程 处理服务端数据
new Thread(new ClientThread(socket)).start();
BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
//客户端的输出流对象
PrintStream printStream = new PrintStream(socket.getOutputStream());
String line = null;
while ((line = keyin.readLine())!= null){
printStream.println(line);
}
}
}
class ClientThread implements Runnable{
private Socket socket;
//保存操作的socket 对象
public ClientThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
//获取输入
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//读取
String line = null;
while ((line=bufferedReader.readLine()) != null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络出错 请重新登录");
System.exit(-1);
}finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (socket != null) {
socket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
bufferedReader= new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
System.out.println("网络异常 请重新登录");
}finally {
try{
if(bufferedReader != null){
bufferedReader.close();
}
if (socket!= null){
socket.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}