"黑马程序员 "网络编程UDP+TCP+HTTP
本篇是学习网络编程的笔记,介绍了网络的模型,网络通讯的要素,网络通信的传输协议。
下图介绍简要介绍了网络编程的轮廓
下图对介绍了TCP,UDP,HTTP传输协议,以及如何使用这些协议进行简单的网络传输操作
以下是使用多线程+UDP实现一个简单的聊天程序的示例代码段1
发送消息端,将发送消息的任务封装到线程的run()
package com.Chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
* 创建UDP传输的发送端。
* 思路:
* 1,建立udp的socket服务。
* 2,将要发送的数据封装到数据包中。
* 3,通过udp的socket服务将数据包发送出去。
* 4,关闭socket服务。
*/
public class Send implements Runnable{
//1,udpsocket服务。使用DatagramSocket对象。
private DatagramSocket ds;
public Send(DatagramSocket ds){
this.ds=ds;
}
@Override
public void run() {
System.out.println("发送端启动!!");
while (true){
BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
String line=null;
try {
while((line=buf.readLine())!=null){
//2,将要发送的数据封装到数据包中。
byte [] bt=line.getBytes();
DatagramPacket dp=new DatagramPacket(bt, bt.length, InetAddress.getByName("192.168.1.104") ,8888);
ds.send(dp);
if(line.equals("over"))break;
}
} catch (Exception e) {
e.printStackTrace();
}
if(ds!=null)ds.close();
}
}
}
接收发送的消息。
package com.Chat;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 建立UDP接收端的思路。
* 1,建立udp socket服务,因为是要接收数据,必须要明确一个端口号。
* 2,创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据.
* 3,使用socket服务的receive方法将接收的数据存储到数据包中。
* 4,通过数据包的方法解析数据包中的数据。
* 5,关闭资源
*/
public class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds){
this.ds=ds;
}
@Override
public void run() {
System.out.println("接收端启动");
while(true){
byte [] buf=new byte[1024];
//2.创建数据包
DatagramPacket dp=new DatagramPacket(buf, buf.length);
try {
// 3,使用接收方法将数据存储到数据包中
ds.receive(dp);
// 4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
String ip=dp.getAddress().getHostAddress();
int port =dp.getPort();
byte [] bt=dp.getData();//数据内容
String data=new String(bt,0,dp.getLength());
System.out.println(ip+"---"+port+":"+data);
if(data.equals("over")){
System.out.println(ip+"退出了");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
启动程序,实现聊天
package com.Chat;
import java.net.DatagramSocket;
import java.net.SocketException;
public class chatTest {
public static void main(String[] args) {
try {
DatagramSocket send=new DatagramSocket(10000);
DatagramSocket rece=new DatagramSocket(8888);
Thread t1=new Thread(new Send(send));
Thread t2=new Thread(new Rece(rece));
t1.start();
t2.start();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
聊天程序到这里就完成了。
以下程序是使用多线程技术+TCP是先一个服务端同时处理多个客户端上传图片的请求。
下面是服务端的实现代码,运行时服务端应该先启动
package com.TcpTest;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadPciServer {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ServerSocket ss=new ServerSocket();
while(true){
Socket s=ss.accept();
new Thread(new uploadTasd(s)).start();
}
}
}
因为客户端执行多个上传任务是需要多线程来实现,所以将上传文件的操作封装成线程任务
package com.TcpTest;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class uploadTasd implements Runnable {
private Socket s;
private static final int SIZE = 1024*1024*2;
public uploadTasd(Socket s) {
super();
this.s = s;
}
@Override
public void run() {
try {
//获取Socket
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"-----------connected");
int count=0;
File dir=new File("c:/upload");
if(!dir.exists()){
System.out.println(dir.mkdirs());
}
File file = new File(dir, ip + ".jpg");
//如果文件已经存在于服务端 ,避免文件的覆盖
while(file.exists()){
file = new File(dir,ip+"("+(++count)+").jpg");
}
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos=new BufferedOutputStream(fos);
BufferedInputStream bis=new BufferedInputStream(s.getInputStream());
int len=0;
while((len=bis.read())!=-1){
bos.write(len);
if(file.length()>SIZE){
System.out.println(ip+"文件体积过大");
bos.close();
s.close();
System.out.println(ip+"...."+file.delete());
return ;
}
}
OutputStream out=s.getOutputStream();
out.write("上传成功!".getBytes());
bos.close();
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面是客户端的实现代码
package com.TcpTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class UploadPicClient {
/**
* @throws Exception
* @throws UnknownHostException
*
*/
public static void main(String[] args) throws UnknownHostException, Exception {
//创建Socket客户端对象
Socket s=new Socket("192.168.1.104",10000);
FileInputStream fis=new FileInputStream(new File("c:/89.jpg"));
OutputStream out=s.getOutputStream();
byte [] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){
out.write(buf,0,len);
}
s.shutdownOutput();//告诉服务端说:这边的数据发送完毕。让服务端停止读取
//读取服务端发回的内容
byte [] btIn=new byte[1024];
InputStream is=s.getInputStream();
int lenIn= is.read(btIn);
String answer=new String(btIn, 0,lenIn);
System.out.println(answer);
fis.close();
s.close();
}
}