Socket学习(一)

目录

一、转换为DataOutputStream和DataInputStream

二、转换为InputStreamReader和OutputStreamWriter

三、由(二)转换为BufferedReader和PrintWriter(为啥不是BufferedWriter?

四、总结我们不难看出我的用以是啥,就是把字节流转换为字符流操作嘛。


与Socket有关的类有两种:

  1. 一种是Serversocket和socket(基于TCP协议,属于长连接,既一直保持连接不断开,除非主动断开或网络原因断开)
  2. 另一种是DatagramSocket(基于UDP协议,属于短连接,既发送数据包之后就断开,不用通知服务端)

我们要学习的是第一种ServerSocket和Scoket


首先,我们要讲一下流相关的知识,因为TCP的Socket(以下用Socket代表TCP的Socket)是通过数据流来传递数据的。

Socket中获取流,总是从Socket这个类中得到的,所以我们在连接过程中基本都是操作Socket这个类,

Socket流(inputstream和outputstream)获取:

private static finally String ip = "127.0.0.1"; 
private static finally String port = "9520";
//这个端口port只要与电脑上软件的端口不相同,与ServerScoket相同就行了 
从Socket获取流:
Socket socket = new Socket( ip ,port );
OutputStream out = socket.getOutputStream();
//这样子我们就能从Server端到Client端传数据或者从Client端到Server端写入数据
InputStream in = socket.getInputStream();
//这样子我们就能从Server端到Client端传数据或者从Client端到Server端读取数据

流的处理:

我们可以把得到的输入输出流进行转换成更容易操作的流对象。

一、转换为DataOutputStream和DataInputStream

String info ="我是要发送的数据,嘻嘻";

DataOutputStream dout =new OutputStreamWriter(out);

DataInputStreamdin = new DataInputStream(in);

其实说这个我只是想说一个方法而已,哈哈哈,这个方法可以解决中文乱码问题

ds.writeUTF(info);//该方法读入一个字符串做参数

d.readUTF();//该方法阻塞,直到收到DataOutputStream发送过来的数据

PS:记住这是配套使用的,不要傻傻顺便用,因为这两个方法实现方法有点特殊

二、转换为InputStreamReader和OutputStreamWriter

InputStreamReader为是字节流通向字符流的桥梁

OutputStreamWriter是字符流通向字节流的桥梁

InputStreamReaderiReader = new InputStreamReader(in);//这里使用输入流作为参数

OutputStreamWriter oWriter = new OutputStreamWriter(out);//这里使用输出流作为参数

同时我们也可以设置两个流的字符集耶。。。

String charsetName = "utf-8";

InputStreamReader iReader = new InputStreamReader(in ,charsetName);//创建使用给定字符集的

OutputStreamWriter oWriter = new OutputStreamWriter(out ,charsetName);//创建使用给定字符集的

PS:为提高效率,我们一般不直接操作这两个类,而是借助下面两个类来操作,

这里的参数输入流输出流可以是Scoket的到输入输出流哦!

三、由(二)转换为BufferedReader和PrintWriter(为啥不是BufferedWriter?

因为BufferedWriter一般也是转换为PrintWriter使用的,所以直接讲PrintWriter吧)

BufferedReader reader = newBufferedReader(iReader);

PrintWriter writer = new PrintWriter(oWriter);

PrintWriter writer = new PrintWriter(oWriter , true);//设置PrintWriter自动刷新

这里我也要说两个方法

String info ="有一次,我是要发送的数据,嘻嘻";

writer.println(info);//这样子就发送好了,自带换行功能

writer.print("out" + "\n");//手动换行模式,哈哈哈

writer.write"out" + "\n");//有没发现这两个都可以做输出啊,我也不知道有啥区别,不深究他们啦

writer.println();//换行函数

writer.flush();//刷新缓冲区

String result = reader.readLine();

PS:作为流我们要写入数据之后是要flush一下的,但是Socket下,我就没有看到flush起作用

倒是我们要手动换行才能将数据刷行,这个要记好了,我被坑了两天(服务端一直接收不到数据),都没有找出原因,最后看其他人写的demo才恍然大悟。

四、总结我们不难看出我的用以是啥,就是把字节流转换为字符流操作嘛。

思路有两个:

一、从Socket获取流转换为(一)中的两个流接受和发送

二、从Socket获取流转换为(二)→(三),字符串更容易操作,而不是操作字节流

有了这些知识希望你能避开我遇到的那些坑。

说完了流的事,我们继续说下实例吧。

服务端:

package server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class MySocketService {
	private static ServerSocket server;
	private static Socket s;
	private static final int port = 9520;

	public static void main(String[] aa) {

		InputStream in = null;
		InputStreamReader reader = null;
		BufferedReader buf = null;

		try {
			server = new ServerSocket(port);
			System.out.println("服务端监听");
			s = server.accept();
			in = s.getInputStream();// 获取输出流
			System.out.println("远程地址:" + s.getRemoteSocketAddress());
			System.out.println("本地端口:" + s.getLocalPort());
			System.out.println("远程端口:" + s.getPort());
			reader = new InputStreamReader(in,"utf-8");
			buf = new BufferedReader(reader);
			System.out.println("开始读取信息.....");
			String info;
			while (true) {
				info = buf.readLine();
				buf.readLine();
				System.out.println("客户端信息:" + info);
				if (info.equals("bye")) {
					break;
				}
			}
			System.out.println("客户端信息" + info);
			System.out.println("接收信息完成");
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}// 创建绑定到特定端口的服务器套接字。
		finally {
			try {
				buf.close();
				reader.close();
				in.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}

		}
	}

}

客户端:

 

 

package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author 小辉辉-华南理工大学广州学院
 */
public class MySocket {

	private static Socket client;
	public static final int port = 9520;
	public static final String ip = "127.0.0.1";

	public static void main(String[] args) {
		String info = null;
		OutputStream out = null;
		OutputStreamWriter ow = null;
		PrintWriter pw = null;
		try {
			client = new Socket(ip, port);
			out = client.getOutputStream();
			ow = new OutputStreamWriter(out, "utf8");
			pw = new PrintWriter(ow, true);
			while (true) {
				// info = scanner.nextLine();
				System.out.print("客户端信息输入:");
				info = new BufferedReader(new InputStreamReader(System.in,
						"utf-8")).readLine();
				System.out.println("服务器信息:"+info);
				pw.println(info);
				//pw.print("out");
				pw.println();
				// pw.print(info);
				// pw.write(info);
				if (info.equals("bye")) {
					break;
				}
				// pw.flush();
			}
			pw.printf("--client--");
			pw.flush();
		} catch (IOException ex) {
			Logger.getLogger(MySocket.class.getName()).log(Level.SEVERE, null,
					ex);
		}
	}

}

在最后我说一下socket断开的是吧。像我这样子用循环写读数据的记得不要输入流输出流关了,因为流一关,socket也会关闭的,我debuger的时候慢慢看变化,当与Socket有关的流一关闭,Socket的isClose属性就会变为true;接着你就好好看报错吧。我上面代码没有写关闭,因为测试代码嘛。。。。关闭时调用Socket的close方法,还有就是把流关闭了。碎觉。掰掰

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值