一. 简介
- 需要建立连接,形成传输数据的通道
- 通过三次握手完成连接,是可靠协议
- 以字节流的方式发送大量数据
二. 通信过程
客户端:
1..创建客户端的socket服务,指定目的主机和端口
2..为了发送数据,应该获取socket中的输出流
3..获取socket中的输入流来获取服务端的反馈数据
4..关闭资源
服务端:
1..创建服务端的ServerSocket服务,并监听一个端口
2..通过accept方法 等待并获取连接过来的客户端socket对象
3..获取客户端发送过来的数据(使用客户端socket的输入流来读取数据)
4..反馈数据到该客户端(使用客户端socket的输出流来写出数据)
5..关闭资源
三. 应用
1..客户端并发登录,服务端处理并反馈
/*
* 客户端
*/
class Client{
public static void main(String[] args) throws Exception {
Socket s = new Socket(InetAddress.getLocalHost(),10000); //客户端建立socket服务,指定目的主机和端口
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //源-读取键盘录入
PrintWriter out = new PrintWriter(s.getOutputStream(),true); //目的-socket输出流,包装成打印流
BufferedReader bin = new BufferedReader(new InputStreamReader(s.getInputStream())); //源-读取socket输入流
int i =0;
for(i =0 ;i<3 ;i++)
{
String line = br.readLine(); //键盘录入的信息
if(line==null)
break;
out.println(line); //写入socket输出流
String mess = bin.readLine(); //服务器反馈的信息
if(mess.contains("欢迎"))
{
System.out.println("Server Message:"+mess);
break;
}
System.out.println("Server Message:"+mess);
}
if(i>=3)
System.out.println("错误次数太多");
s.close();
br.close();
}
}
/*
*服务端
*/
class Server {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10000); //服务端建立ServerSocket服务,监听指定端口
while(true)
{
Socket s = ss.accept();
new Thread(new ServerThread(s)).start(); //进来一个用户,则开启一个线程
}
}
}
class ServerThread implements Runnable{
private Socket s;
ServerThread(Socket s){
this.s = s;
}
public void run() {
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"已连接");
try{
for(int i =0 ;i<3;i++)
{
BufferedReader bfr = new BufferedReader(new FileReader("E:\\user.txt")); //源-服务端数据文件或数据库,包装成BufferedReader
BufferedReader bin = new BufferedReader(new InputStreamReader(s.getInputStream())); //源-客户端提交的数据
PrintWriter out = new PrintWriter(s.getOutputStream(),true); //目的-socket输出流,包装成打印流
String name = bin.readLine();
String line = null;
boolean flag = false;
while((line = bfr.readLine())!=null)
{
if(line.equals(name))
{
flag = true;
break;
}
}
if(flag == true)
{
System.out.println(name+"已登录");
out.println("欢迎"+name); //将信息反馈给客户端
}
else
out.println("用户名不存在");
}
s.close();
}catch(Exception e){
throw new RuntimeException(ip+"校验失败");
}
}
}
2..客户端并发上传图片,服务端接收并反馈
/*
* 客户端
*/
class UploadClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket(InetAddress.getLocalHost(),9999);
BufferedOutputStream bout = new BufferedOutputStream(s.getOutputStream()); //目的-socket输出流
FileInputStream fin = new FileInputStream("E:\\晴天.mp3"); //读文件并写入socket输出流
int len = 0;
while((len = fin.read())!=-1)
{
bout.write(len);
}
s.shutdownOutput(); //写完..结束标记
BufferedReader bin = new BufferedReader(new InputStreamReader(s.getInputStream())); //源-读取socket输入流
String mess = bin.readLine(); //服务器反馈的信息
System.out.println(mess);
s.close();
fin.close();
}
}
/*
* 服务端
* /
class UploadServer{
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(9999);
while(true)
{
Socket s = ss.accept();
new Thread(new UploadThread(s)).start();
}
}
}
class UploadThread implements Runnable {
private Socket s = null;
UploadThread(Socket s)
{
this.s = s;
}
public void run(){
String ip = s.getInetAddress().getHostAddress();
try {
System.out.println(ip+"已连接");
int time = (int) System.currentTimeMillis();
BufferedInputStream bin = new BufferedInputStream(s.getInputStream()); //源-socket输入流,客户端发来的数据
FileOutputStream fi = new FileOutputStream("F:\\"+time+".mp3"); //目的-磁盘,将客户端发来的文件写入本地
int len;
while((len=bin.read())!=-1)
{
fi.write(len);
}
PrintWriter out = new PrintWriter(s.getOutputStream(),true); //目的-socket输出流,包装成打印流
out.println("上传成功"); //反馈给客户端
fi.close();
s.close();
} catch (Exception e) {
throw new RuntimeException(ip+"上传失败");
}
}
}