JAVA之旅三十三.docx
- 文档编号:25799077
- 上传时间:2023-06-14
- 格式:DOCX
- 页数:18
- 大小:17.81KB
JAVA之旅三十三.docx
《JAVA之旅三十三.docx》由会员分享,可在线阅读,更多相关《JAVA之旅三十三.docx(18页珍藏版)》请在冰豆网上搜索。
JAVA之旅三十三
JAVA之旅(三十三)
一.TCP
说完UDP,我们就来说下我们应该重点掌握的TCP了
TCP传输
Socket和ServiceSocket
建立客户端和服务端
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
同样的,我们的客户端和服务端都是两个独立的应用
我们通过查阅API文档发现,该对象在建立的时候,就可以去连接指定主机,因为tcp是面向连接的,所以在建立socket服务时,就要有服务存在,并成功连接,形成通路后,在该通道进行数据传输
所以我们用代码来看下他的步骤
客户端
packagecom.lgl.hellojava;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
import.ServerSocket;
import.Socket;
import.UnknownHostException;
publicclassTcpClient{
publicstaticvoidmain(String[]args){
try{
//1.创建客户端的服务,传地址和端口
Sockets=newSocket("192.168.1.102",10000);
//2.为了发送数据,应该获得socket流中的输出流
OutputStreamout=s.getOutputStream();
out.write("你好".getBytes());
s.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
服务端
packagecom.lgl.hellojava;
importjava.io.IOException;
importjava.io.InputStream;
import.ServerSocket;
import.Socket;
/**
*定义端点接收数据打印出来
*服务端:
*1.建立服务端的socket服务,servicesocket,并监听一个端口
*2.获取连接过来的客户端对象,通过accept方法,这个方法是阻塞的,没有连接就会等
*3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该对象的读取流
*4.关闭服务端(可选操作)
*@authorLGL
*
*/
publicclassTcpService{
publicstaticvoidmain(String[]args){
try{
//1.建立连接,监听端口
ServerSocketss=newServerSocket(10000);
//2.连接客户端对象
Socketaccept=ss.accept();
//获取ip
Stringip=accept.getInetAddress().getHostAddress();
//3.获取客户端发送过来的数据
InputStreamin=accept.getInputStream();
//4.开始读取
byte[]buf=newbyte[1024];
intlen=in.read(buf);
System.out.println(newString(buf,0,len));
//5.关闭
ss.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
二.TCP互相传输
我们在来写一个实例去说明,他们的互访动作,这里为了写起来方便,就写在一个类中了
packagecom.lgl.hellojava;
importjava.io.IOException;
importjava.io.InputStream;
importjava.io.OutputStream;
import.ServerSocket;
import.Socket;
import.UnknownHostException;
/**
*客户端发送信息,服务端收到,反馈信息
*
*@authorLGL
*
*/
publicclassTcp{
publicstaticvoidmain(String[]args){
try{
Sockets=newSocket("192.168.1.102",10005);
OutputStreamout=s.getOutputStream();
out.write("我是客户端".getBytes());
InputStreamin=s.getInputStream();
byte[]buf=newbyte[1024];
intlen=in.read(buf);
System.out.println(newString(buf,0,len));
s.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
/**
*服务端
*@authorLGL
*
*/
classServer{
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(10005);
Sockets=ss.accept();
InputStreamin=s.getInputStream();
byte[]buf=newbyte[1024];
intlen=in.read(buf);
System.out.println(newString(buf,0,len));
OutputStreamout=s.getOutputStream();
out.write("收到后反馈".getBytes());
s.close();
ss.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
三.复制文件
同样的这里也是使用的流,我们具体来看下怎么去操作,我们同样的,写在一个类中
packagecom.lgl.socket;
importjava.io.BufferedReader;
importjava.io.FileReader;
importjava.io.FileWriter;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
import.ServerSocket;
import.Socket;
import.UnknownHostException;
publicclassFileClient{
publicstaticvoidmain(String[]args){
try{
Sockets=newSocket("192.168.1.102",10006);
BufferedReaderbufr=newBufferedReader(newFileReader("test.txt"));
PrintWriterpw=newPrintWriter(s.getOutputStream(),true);
Stringline=null;
while((line=bufr.readLine())!
=null){
pw.println(line);
}
pw.print("over");
BufferedReaderbufIn=newBufferedReader(newInputStreamReader(
s.getInputStream()));
Stringstr=bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
classFileServer{
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(10006);
Sockets=ss.accept();
BufferedReaderbufIn=newBufferedReader(newInputStreamReader(
s.getInputStream()));
PrintWriterout=newPrintWriter(newFileWriter("test1.txt"),true);
Stringline=null;
while((line=bufIn.readLine())!
=null){
if("over".equals(line))
break;
out.println(line);
}
PrintWriterpw=newPrintWriter(s.getOutputStream(),true);
pw.println("上传成功");
out.close();
s.close();
ss.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
四.上传图片
我们再来看下图片是怎么上传的,我们先来分析下步骤
客户端
1.服务端点
2.读取客户端已有的图片数据
3.通过socket,发送给服务端
4.读取服务端反馈的信息
5.关闭资源
**
*客户端
*
*@authorLGL
*
*/
publicclassPicClient{
publicstaticvoidmain(String[]args){
try{
Sockets=newSocket("192.168.1.102",10009);
FileInputStreamfis=newFileInputStream("1.png");
OutputStreamout=s.getOutputStream();
byte[]buf=newbyte[1024];
intlen=0;
while((len=fis.read(buf))!
=-1){
out.write(buf,0,len);
}
//告訴服务端数据写完
s.shutdownInput();
InputStreamin=s.getInputStream();
byte[]bufn=newbyte[1024];
intnum=in.read(bufn);
System.out.println(newString(bufn,0,num));
fis.close();
s.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
服务端
直接看代码
/**
*服務端
*@authorLGL
*
*/
classPicServer{
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(10009);
Sockets=cept();
InputStreamin=s.getInputStream();
FileOutputStreamfos=newFileOutputStream("2.png");
byte[]buf=newbyte[1024];
intlen=0;
while((len=in.read(buf))!
=-1){
fos.write(buf,0,len);
}
OutputStreamout=s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
ss.close();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
其实跟I/O区别真不大,但是概念一定要了解清楚
五.多并发上传
多并发这个概念就是多人互动了,这对服务器的负荷还是有考究的,这里呢,我们就模拟一下,多人上传图片的场景,我们是怎么做的?
我们还是在上传图片的那份代码上更改
首先我们可以确定的是,这是服务端的代码
这个服务端有个局限性,当A客户端连接之后,被服务端获取到,服务端就在执行代码了,这个时候如果B客户端连接只有等待,这就是我们需要多并发的原因了,为了让多个客户端同时连接,服务端最好就是讲每个客户端封装到一个单独的线程中,这样就可以同时处理多个客户端请求
如何定义线程?
只要明确了每个客户端要在服务端执行的代码即可
/**
*服務端
*
*@authorLGL
*
*/
classPicServer{
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(10009);
while(true){
Sockets=ss.accept();
newThread(newPicThread(s)).start();
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
/**
*并发线程
*@authorLGL
*
*/
classPicThreadimplementsRunnable{
privateSockets;
publicPicThread(Sockets){
this.s=s;
}
@Override
publicvoidrun(){
try{
Stringip=s.getInetAddress().getHostAddress();
System.out.println("ip:
"+ip);
longmillis=System.currentTimeMillis();
Filefile=newFile(millis+".png");
InputStreamin=s.getInputStream();
FileOutputStreamfos=newFileOutputStream(file);
byte[]buf=newbyte[1024];
intlen=0;
while((len=in.read(buf))!
=-1){
fos.write(buf,0,len);
}
OutputStreamout=s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
}catch(Exceptione){
thrownewRuntimeException("上传失败");
}
}
}
其实我写的代码还是有点烂的,但是思想在就好,我们得先把思想学会了
六.多并发登录
上面说的多并发的上传,实在服务端端,现在我们来说下登录,是作用在客户端
packagecom.lgl.socket;
importjava.io.BufferedReader;
importjava.io.FileReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
import.ServerSocket;
import.Socket;
import.UnknownHostException;
publicclassLoginClient{
publicstaticvoidmain(String[]args){
try{
Sockets=newSocket("192.168.1.102",10008);
BufferedReaderbufr=newBufferedReader(newInputStreamReader(
System.in));
PrintWriterout=newPrintWriter(s.getOutputStream(),true);
BufferedReaderbufIn=newBufferedReader(newInputStreamReader(
s.getInputStream()));
for(inti=0;i<3;i++){
Stringline=bufr.readLine();
if(line==null){
break;
}
out.println(line);
Stringinfo=bufIn.readLine();
System.out.println("info:
"+info);
if(info.contains("欢迎")){
break;
}
}
bufr.close();
s.close();
}catch(UnknownHostExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
/**
*服务端
*
*@authorLGL
*
*/
classLoginServer{
publicstaticvoidmain(String[]args){
try{
ServerSocketss=newServerSocket(10008);
while(true){
Sockets=ss.accept();
newThread(newUserThread(s)).start();
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
}
}
/**
*并发登陆
*
*@authorLGL
*
*/
classUserThreadimplementsRunnable{
privateSockets;
publicUserThread(Sockets){
this.s=s;
}
@Override
publicvoidrun(){
for(inti=0;i<3;i++){
try{
BufferedReaderbufrIn=newBufferedReader(
newInputStreamReader(s.getInputStream()));
Stringname=bufrIn.readLine();
//模拟读取数据库的用户名
BufferedReaderbufr=newBufferedReader(newFileReader(
"user.txt"));
PrintWriterout=newPrintWriter(s.getOutputStream(),true);
Stringline=null;
booleanflag=false;
while((line
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAVA 三十三