前一段时间做项目,涉及到TCP和UDP的使用,长期做单机的东西,一下跳到网络真的不适应,记录一下这些东西的入门级使用。
总体来说,TCP和UDP的使用流程分三步,只是TCP和UDP使用的类有所不同
图一 总体流程
具体使用的类在表一中列出,TCP是使用流传输,而UDP将数据打包发送。
TCP/IP | UDP | |
Socket | Scoket | DatagramSocket |
Outputstream | DataOutputStream/PrintWirter | DatagramPacket |
send | Outputstrem.flush(); | DatagramPacket.send |
客户端-TCP使用方法
Socket socket = null;
DataOutputStream out = null;
//DataInputStream in = null;
try {
//Socket实例化
socket = new Socket();
//IP地址对象构造
InetAddress addr = Inet4Address.getByName(ip);
//1)Socket链接服务器(指明端口和IP)
socket.connect(new InetSocketAddress(addr, port));
////设置超时限制(未使用)
// socket.setSoTimeout(2000);
//2)获取Socket对象的OutputStream
out = new DataOutputStream(socket.getOutputStream());
//in = new DataInputStream(socket.getInputStream());
if (out != null) {
//特殊格式(可以忽略)
String value = msg;
byte[] data = value.getBytes();
int size = data.length;
byte[] bt = new byte[4];
bt[0] = (byte) size;
bt[1] = (byte) (size >> 8);
bt[2] = (byte) (size >> 16);
bt[3] = (byte) (size >> 24);
//写入数据
out.write(bt);
out.write(data);
//3)传输数据
out.flush();
}
} catch (Exception e) {
// System.out.println(e.getMessage());
} finally {
try {
if (out != null)
out.close();
//if (in != null)
//in.close();
if (socket != null)
socket.close();
} catch (IOException e) {
}
}
客户端-UDP使用方法
DatagramSocket socket;
try {
//特殊格式(可以忽略)
byte[] data = msg.getBytes(charset);
int size = data.length;
byte[] bt = new byte[4];
bt[0] = (byte) size;
bt[1] = (byte) (size >> 8);
bt[2] = (byte) (size >> 16);
bt[3] = (byte) (size >> 24);
//1)DatagramSocket对象实例化
socket = new DatagramSocket();
//IP地址对象实例化
InetAddress ipAdress = InetAddress.getByName(ip);
//2)构造DatagramPacket对象,用于封装和发送数据
DatagramPacket packet = new DatagramPacket(data, data.length,
ipAdress, port);
//3)数据发送
socket.send(packet);
socket.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
服务器接收端TCP需要通过ServerSocket与设备端口进行链接,接收Socket利用InputStream获取数据;UDP依然利用DatagramSocket与端口链接,DatagramPacket获取数据。
服务器端 - TCP
ServerSocket serverSocket=new ServerSocket(12345);
System.out.println("Create Serversocket");
////设置超时(未使用)
//serverSocket.setSoTimeout(5000);
//2>接受Socket
Socket socket=serverSocket.accept();
System.out.println("accept");
//3>获取Socket的InoutStream
InputStream input=socket.getInputStream();
byte[] buffer=new byte[1024*4];
//4>读取数据
input.read(buffer);
System.out.print(new String(buffer).trim());
//5>关闭Socket
socket.close();
serverSocket.close();
serverSocket=null;
服务器端-UDP
//1>构建DatagramSocket链接端口
DatagramSocket socket=new DatagramSocket(12345);
byte[] buffer=new byte[1024];
//2>构建DatagramPacket用于接收数据
DatagramPacket packet=new DatagramPacket(buffer, buffer.length);
//3>获取数据
socket.receive(packet);
System.out.println("Receive");
//4>设置偏移量的方法,解决了传输数据中的乱码问题
System.out.println(new String(packet.getData(),packet.getOffset(),packet.getLength()));
//5>一定要关闭,否则影响下次使用
socket.close();
常见问题:
1>ECONNREFUSED 问题 :这个问题困扰了我好久,其实处理起来比较容易,产生的原因是端口被占,或者ip错误,需要仔细检查IP和端口号,端口号可以设置大一些,1024一下的端口号容易被占用。
2>程序在socket创建或连接的时候程序崩溃 :我出现这种情况大多是服务器没有开,并且使用的TCP协议,打开就好了
3>服务器端接收不到数据 :我使用的是校园网和实验室的无线网,只有两种情况可以接受到数据,第一种,服务器和手机终端连接在同一个路由器上;第二种服务器连接在校园网上,手机连接没有限制。原因暂时还不太清除
来源:oschina
链接:https://my.oschina.net/u/162807/blog/214872