java 网络 socket TCP / UDP / catch 语句块捕捉到异常后,继续执行语句块后面的代码

来源:互联网 发布:转录组数据上传 编辑:程序博客网 时间:2024/05/16 17:31

java 网络 socket TCP / server 端

package test.java.Net;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.net.*;/** *  * @author jalo * 如果是客户端和服务端交互读写的话,两方必须,有一个先写后读,有一个先读后写 */public class TCPServer { //在网络应用程序的编写中,server / client一块写。在启动的时候,也是首先起server,再起clientpublic static void main(String args[]) throws IOException  {System.out.println("server");ServerSocket ss = null;try {ss = new ServerSocket(6666);} catch (IOException e) {System.out.println("不能监听端口" + e);System.exit(0);//如果写的严谨一点,这里应该系统退出,不继续往下执行//catch 抛出异常,直接执行后面catch 语句块后面的语句} //server的应用程序往往是不间断的在运行,他在等待着客户端的连接。//客户端一连上,他才会执行。这是阻塞式连接。这句话完成,这个端口已经监听。这时我们写client 端////////////////client 端已经申请连接我了,我server 是不是接收这个连接请求还是个问题while(true){//以下几句如果不加while(true),那只能接受一个连接。有了,则连一个我打印一个,然后再等待下一个。这才是真正的server,7*24*365Socket s = ss.accept();     //accept 这个方法是阻塞式的,到这就停止,如果没有任何客户端连上来,他就在那傻傻的不动//,socket 叫做和client 端的一个连接,accept是接受的意思。这个方法的作用://作为一个服务器端来说,他可以接收很多很多客户端的连接,如图1中server 端新建的红色socket 。System.out.println("accept ");InputStream is = s.getInputStream();  //我这个s(socket) 就是连着客户端的socket,所以我这里拿着的输入管道就是客户端的输出管道  //这是一个连接,所以是一根管道DataInputStream dis = new DataInputStream(is);//s.getInetAddress(),s.getPort() ,也就是返回的客户端IP,port,Returns the address to which the socket is connected. System.out.println("A client connect , it says "+dis.readUTF());//readUTF()也是阻塞式的(这里也可以放.readLine()即也是阻塞式的),如果对方不写dis.close();//东西过来,我也在这傻傻等着,一直对方写东西过来为止。这个方法阻塞住,不能再接收其他的client 连接请求s.close();//这些都是同步式的,所以不好,但是java 已经推出了异步式的网络编程,意思是我accept() 之后就相当于//注册一下,然后我就走了,我该干什么干什么,什么时候就客户端连上,系统通知我,我再连上,这就叫异步式。这才是效率最高的。//异步IO,VC里面,这种网络编程的模型巨多无比,有最底层的,有用windows 自己提供的API 接口的,有用同步式的 /异步式的,还有一种最有效率的//叫做iocompletionport,(io 完成接口,)不仅是异步式的,而且还有一个线程池在不停等待,只要cpu 多,那么处理的吞吐量就会特别大//就是同时有好多人连接也没什么关系,java 1.6达打不到这个层次,但是既然java已经提供异步式,那么他就能处理很多很多的连接了。现在很多程序//都是用java 编写的TCP 的server,比如tomcat,jboss,也已经证明大量的连接可以运行在java 写的server 上面。但是这不是将来我们工作的重点。    //}///////////////一旦我们连上了,c 和 s 就通过管道来说话,通过流来说话}}




java 网络 socket TCP / client 端

import java.io.DataOutputStream;import java.io.OutputStream;import java.net.*;public class TCPClient {public static void main(String args[]) throws Exception{System.out.println("client");//client 端这边的插座叫什么了?socket.服务端的叫serversocketSocket s = new Socket("127.0.0.1",6666);//127.0.0.1 叫本机IP,指定到你要连接到哪个端口上,server 那个端口,那边有人在监听6666//这边就连到6666 。这时候,client 这边的端口,系统随机选择,没必要我绑定在哪个端口上,再和你6666建立连接。//反正只要咱们俩建立起来连接,你这个端口就永远归我所用。你server 再发别的东西,很显然你发不到别的地方去,你就//只能发到我client 端的这个端口上。//////////////client 这端往外说,就是输出流,OutputStream os = s.getOutputStream();//通过这个可以看出,如图1,连接建立起来后,相当于有连接里面有两根管道,一根输入  //一根输出DataOutputStream dos = new DataOutputStream(os);Thread.sleep(3000000);dos.writeUTF("hello server");dos.flush();dos.close();s.close();    //socket 也是一个连接,说完话,也自己关掉,清理好。}}


java 网络 socket UDP / server 端。严格意义上讲,UDP 没有server 和 client 的概念,因为他不区分客户端的socket 和server 的socket

对于UDP来说,他的socket 也是插座,但是无线连接,不像TCP,需要连起来一个通道,才能发数据


udp server

package test.java.Net;import java.io.ByteArrayInputStream;import java.io.DataInputStream;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;import java.nio.ByteBuffer;/** *  * @author jalo * 如果接收的是long 型,有两种方式,第一种是写出端直接借助ByteArrayOutputStream和DataOutputStream * 接收端直接用这个byte[]数组去初始化ByteArrayInputStream,再包上一层DataInputStream,去readLong * 第二种是用本例中的byteArrayToLong(byte[])去转化成long 类型 * */public class udpserver {public static long byteArrayToLong(byte[] buf) {  //long类型的前ByteBuffer buffer = ByteBuffer.allocate(8);buffer.put(buf, 0, 8);      buffer.flip();//need flip       return buffer.getLong();  }public static void main(String[] args) throws IOException {// udpserverInetSocketAddress isa = new InetSocketAddress("127.0.0.1", 40000);//注意这个是udp 的端口,udp 和tcp 不公用端口,他们都有40000端口DatagramSocket ds = new DatagramSocket(isa);byte []buf = new byte[1024]; // 1024长度的byte数组这个是1KBDatagramPacket packet = new DatagramPacket(buf, 1024);while(true){ds.receive(packet);//也是阻塞式的方法。注意tcp是直接拿到流(因为有连接),在流上面包DataInputStream 即可实现各种类型的读写(readLong等)   //UDP不行,UDP只能拿数据包,然后分析里面的内容,如果是long,还得去转化(通过ByteArrayInputStream(byte[]))String info = new String(buf,0,packet.getLength());//此时这里是乱码,因为传过来的是long 类型,你给解析成string类型了byte bufIn[] = new byte[1024];ByteArrayInputStream bais = new ByteArrayInputStream(buf);// 可以用buf 直接DataInputStream dis = new DataInputStream(bais);//long receiveLongVar = byteArrayToLong(buf);long receiveLongVar = dis.readLong();System.out.println("receive is "+receiveLongVar+""+"接收字节的长度为:"+packet.getLength()+"client 的端口是"+ds.getPort());//1024是数据包的大小,接收长度不是1024,}}}



udp client

import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetSocketAddress;import java.net.SocketException;public class udpclient {public static void main(String[] args) throws IOException {InetSocketAddress isa = new InetSocketAddress("127.0.0.1", 40000);DatagramSocket ds = new DatagramSocket(); //这个可以给参数,传端口号,表示我 udp client 端的端口//byte buf[] = "我是客户端".getBytes();/////////以下是发送long 类型的方法,转化成内存中的byte 数组,其他类型也这样操作即可,即借助ByteArrayOutputStream,DataOutputStreamlong l = 1132234599919232343L;//ByteArrayOutputStream此类实现了一个输出流,其中的数据被写入一个 byte 数组。无论你写什么,最后都转化成字节数组存在内存里,这样省空间ByteArrayOutputStream baos = new ByteArrayOutputStream();// 这个是内存,是字节数组,但是具体大小不用管,直接往里写就写DataOutputStream dos = new DataOutputStream(baos);  dos.writeLong(l);//此时这个long 类型数已经被写到字节数组里byte buf1[] = baos.toByteArray();//拿到内存中的byte 数组,buf1.length是你有多少数据,length就多长///////////System.out.println(String.valueOf(l).getBytes().length);//string 转化成long类型,这是19字节。如果按照long直接转byte 数组,则才8字节(因为long本身是8字节)ds.send(new DatagramPacket(buf1, buf1.length,isa)); // 第二个参数是接收长度,注意第三个参数是InetSocketAddress//为什么TCP的时候,传东西不需要ip + 端口,因为udp 无连接,你包给路由器,路由器总得知道,你这个包要到哪去。TCP有连接//}}












0 0
原创粉丝点击