记录一下网络编程入门的简单程序
TCP通信
实现基本的客户端和服务器端互相发送数据功能
客户端:
public class MyTcpClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//客户端创建与服务器端通信的socket对象,绑定服务器IP地址以及进程端口号
Socket socket = new Socket("127.0.0.1",6666);//服务器IP地址+服务器端口号;127.0.0.1表示本机
//使用socket字节输出流
OutputStream os = socket.getOutputStream();
//向服务器发送数据
os.write("你好,我是客户端".getBytes());
//使用socket字节输入流
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
//读取服务器端发送的数据
int len = is.read(bytes);
System.out.println("客户端收到服务器的应答:"+new String(bytes,0,len));
//释放连接
socket.close();
}
}
服务器端:
public class MyTcpServer {
public static void main(String[] args) throws IOException{
//创建服务器socket并分配端口号
ServerSocket server = new ServerSocket(6666);
//用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例
Socket socket = server.accept();
//获取客户端输入字节流,
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
//读取客户传过来的数据
int len = is.read(bytes); //is.read(bytes)将字节输入流中的数据存储到bytes数组中
System.out.println("服务器端收到的客户发送的数据:"+new String(bytes, 0, len));
//获取客户端输出字节流,
OutputStream os = socket.getOutputStream();
//向客户端发送数据
os.write("收到谢谢".getBytes());
//释放连接
socket.close();
server.close();
}
}
实现基本的客户端向服务器上传文件功能
客户端:
public class MyTcpClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//客户端创建与服务器端通信的socket对象,绑定服务器IP地址以及进程端口号
Socket socket = new Socket("127.0.0.1",6666);//服务器IP地址+服务器端口号
//新建本地字节输入流对象从本地读取文件
BufferedInputStream filein = new BufferedInputStream(new FileInputStream("/Users/apple/image/0.png"));
//使用socket字节输出流,
OutputStream os = socket.getOutputStream();
//向服务器发送读取到的本地文件
int len = 0;
byte[] bytes = new byte[1024];
while((len = filein.read(bytes)) != -1){
os.write(bytes,0,len);
}
//客户端发送数据完毕,结束Socket输出流的写入操作,告知服务器端
socket.shutdownOutput();
//使用socket字节输入流
InputStream is = socket.getInputStream();
//读取服务器端回复的数据
int lenth = is.read(bytes);
System.out.println("客户端收到服务器的应答:"+new String(bytes,0,lenth));
//释放连接
filein.close();
socket.close();
}
服务器端:
public class MyTcpServer {
public static void main(String[] args) throws IOException{
//创建服务器并分配端口号
ServerSocket server = new ServerSocket(6666);
//获取客户端socket
Socket socket = server.accept();
InetAddress ipObj = socket.getInetAddress();
System.out.println(ipObj.getHostAddress()+"登录服务器");
//获取socket输入字节流
InputStream is = socket.getInputStream();
//服务器端存放文件的位置
File file = new File("/Users/apple/download");
if(!file.exists())
file.mkdir();
//服务器端使用本地字节输出流写文件到指定位置
String fileName = "image_"+System.currentTimeMillis()+".png";
BufferedOutputStream fileout = new BufferedOutputStream(new FileOutputStream(file+"/"+fileName));
//读取客户传过来的数据
byte[] bytes = new byte[1024];
int len = -1;
while((len = is.read(bytes)) != -1){
//向本地文件目录写入从客户端读取的文件
fileout.write(bytes,0,len);
}
//获取客户端输出字节流
OutputStream os = socket.getOutputStream();
//向客户端发送数据
os.write("上传成功".getBytes());
//释放链接
fileout.close();
socket.close();
}
}
使用多线程改进上传功能
客户端不做改变,服务器端改变:
public class MyTcpServer {
public static void main(String[] args) throws IOException{
//创建服务器并分配端口号
ServerSocket server = new ServerSocket(6666);
//让服务器一直监听
while(true){
//获取客户端socket
Socket socket = server.accept();
//使用多线程提高程序效率,有客户端上传,则开启一个线程,完成文件上传
new Thread(){
public void run(){
try{
InetAddress ipObj = socket.getInetAddress();
System.out.println(ipObj.getHostAddress()+"登录服务器");
//获取socket输入字节流
InputStream is = socket.getInputStream();
//服务器端存放文件的位置
File file = new File("/Users/apple/download");
if(!file.exists()){
file.mkdir();
}
//服务器端使用本地字节输出流写文件到指定位置
String fileName = "image_"+System.currentTimeMillis()+".png";
BufferedOutputStream fileout = new BufferedOutputStream(new FileOutputStream(file+"/"+fileName));
//读取客户传过来的数据
byte[] bytes = new byte[1024];
int len = -1;
while((len = is.read(bytes)) != -1){
//向本地文件目录写入从客户端读取的文件
fileout.write(bytes,0,len);
}
//获取客户端输出字节流
OutputStream os = socket.getOutputStream();
//向客户端发送数据
os.write("上传成功".getBytes());
//释放链接
is.close();
os.close();
fileout.close();
socket.close();
}catch (IOException e){
System.out.println(e);
}
}
}.start();
}
}
}
B/S结构服务器端
例如在浏览器中输入网址后,服务器所做的就是根据用户在浏览器中的输入请求找到本地服务器端相应目录中的HTML等文件返回给用户。例如我下载了bilibili网页,将它放入我的Java项目mynetwork下面时,启动服务器端口号为8080的java文件,则在浏览器中请求页面http://127.0.0.1:8080/mynetwork/影视-哔哩哔哩 (゜-゜)つロ 干杯_-bilibili.html 时,可以获取相关的信息
第一行中间的信息则为所请求的页面在服务器中的地址,不太对。。。问题不是很清楚,打开页面后获取到的地址和本地名字不一样,以后再看- -
服务器端代码如下:
public class MyTcpServer {
public static void main(String[] args) throws IOException{
//创建服务器并分配端口号
ServerSocket server = new ServerSocket(8080);
//让服务器一直监听
while(true){
//获取客户端socket
Socket socket = server.accept();
//浏览器解析html页面时,如果有图片就会单独创建一个线程,读取服务器的图片,
//因此需要让服务器一直处于监听状态,客户请求一次,服务器回写一次
new Thread(){
public void run(){
try{
//获取socket字节输入流
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
//获取用户请求,第一行即为用户请求的地址,例如 GET /
String line = br.readLine();
System.out.println(line);
String htmlpath = line.split(" ")[1].substring(1);
//创建本地字节输入流读取html文件
FileInputStream fi = new FileInputStream(htmlpath);
//获取字节输出流
OutputStream os = socket.getOutputStream();
//写入http相应头,固定写法
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content-Type:text/html\r\n".getBytes());
//必须写入空行,否则浏览器不解析
os.write("\r\n".getBytes());
//将服务器读取到的html文件写回给用户
byte[] bytes = new byte[1024];
int len = -1;
while((len = fi.read(bytes)) != -1){
os.write(bytes,0,len);
}
//释放链接
fi.close();
socket.close();
}catch (IOException e){
System.out.println(e);
}
}
}.start();
}
}
}
因为读取的地址不对,打不开- -