标签:ethos steam 读写 端口 exce print row 图片 原因
网络通信协议
static InetAddress getByName() | 给定主机名确定IP |
static InetAddress getLocalhost() | 返回本地主机地址和主机名 |
String getHostName() | 返回主机名 |
String getHostAddress() | 返回主机IP |
InetAddress Inet=InetAddress.getLocalHost();
InetAddress Inet1=InetAddress.getByName("www.baidu.com");
System.out.println(Inet);
System.out.println(Inet1);
System.out.println(Inet.getHostName());
System.out.println(Inet.getHostAddress());
运行结果:
UDP
服务端:
InetAddress inet=InetAddress.getByName("127.0.0.1"); byte []buf="你好,世界!".getBytes(); //整个数组全发送出去 DatagramPacket dp=new DatagramPacket(buf,buf.length,inet,6000); DatagramSocket ds=new DatagramSocket(); ds.send(dp); ds.close();
客户端:
byte [] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); //套接字绑定端口号 DatagramSocket ds=new DatagramSocket(6000); ds.receive(dp); //获取报文长度,避免打印空白字符 int length=dp.getLength(); //获取客户端端口口号 InetAddress ip=dp.getAddress().getHostAddress(); int port=dp.getPort(); System.out.println(ip+":"+port); System.out.println(new String(buf,0,length)); ds.close();
注:客户端每次获取的端口好都有不一样,而且不是6000,原因是系统随机分配一个端口去和监听的6000端口对接。
可改造成while循环进行持续的发送接收。
TCP
客户端:
Socket socket=new Socket("127.0.0.1",1234); //向服务器发送数据 OutputStream out=socket.getOutputStream(); out.write("世界你好".getBytes()); //接收服务器的数据 InputStream in=socket.getInputStream(); byte[] buf=new byte[1024]; in.read(buf); System.out.println(new String(buf,0,buf.length)); socket.close();
服务端:
ServerSocket ss=new ServerSocket(1234); //获取客户端的对象 Socket s=ss.accept(); //接收数据 InputStream in=s.getInputStream(); byte[] buf=new byte[1024]; in.read(buf); System.out.println(new String(buf,0,buf.length)); //向客户端发送数据 OutputStream out=s.getOutputStream(); out.write("收到了,谢谢".getBytes()); s.close(); ss.close();
注:连接一旦建立,系统就会自动创建一个IO流对象,这时候要用socket对象去get这个流对象来进行读写。
服务端没有socket对象,会通过serversocket对象accept()获取到客户端对象,也是这样来对客户端进行区分。
outputstream和inputsteam 的区分,把端当成一条steam即可,发送理解为拿数据出来-->out,接收理解为把数据放进去-->in。
TCP上传图片
客户端:
Socket s=new Socket("127.0.0.1",2222); OutputStream out=s.getOutputStream(); //将文件以字节读入入流中 FileInputStream fis=new FileInputStream("c:\\k.jpg"); byte[]buf=new byte[1024]; //len用来记录有效长度 int len; while((len=fis.read(buf))!=-1){ out.write(buf,0,len); } s.shutdownOutput(); //获取服务端返回的数据 InputStream in=s.getInputStream(); len=in.read(buf); System.out.println(new String(buf,0,len)); s.close();
服务端:
ServerSocket ss=new ServerSocket(2222); Socket s=ss.accept(); InputStream in=s.getInputStream(); byte [] buf=new byte[1024]; File filename=new File("d:\\upload"); //如果没有文件夹就会创建 if(!filename.exists()){filename.mkdirs();} String str="wei"+System.currentTimeMillis()+newRandom().nextInt(999999)+".jpg"; FileOutputStream fos=new FileOutputStream(filename+"\\"+str); int len=0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } //反馈结果给客户端 s.getOutputStream().write("上传成功".getBytes()); fos.close(); s.close(); ss.close();
变量len的意义在于记录数组改变的有效长度,读写的时候读写有效长度,防止读写原数组保留内容。
TCP实现多线程上传图片
public class upload implements Runnable{ //将获得的socket传入 private Socket s; public upload(Socket s){this.s=s;} @Override public void run() { try{ InputStream in=s.getInputStream(); byte [] buf=new byte[1024]; File filename=new File("d:\\upload"); //如果没有文件夹就会创建 if(!filename.exists()){filename.mkdirs();} String str="wei"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg"; FileOutputStream fos=new FileOutputStream(filename+"\\"+str); int len=0; while((len=in.read(buf))!=-1){ fos.write(buf,0,len); } //反馈结果给客户端 s.getOutputStream().write("上传成功".getBytes()); fos.close(); s.close(); }catch(IOException e){ System.out.println(e); throw new RuntimeException("上传错误!"); } } }
public class UploadServer { public static void main(String[] args) throws IOException{ ServerSocket ss=new ServerSocket(2222); while(true){ Socket s=ss.accept(); new Thread(new upload(s)).start(); } } }
注:客户端无需修改,当服务端接收到客户端发送的socket的对象时,开启线程,执行重写的run方法。
标签:ethos steam 读写 端口 exce print row 图片 原因
原文地址:https://www.cnblogs.com/findlisa/p/10770106.html