【学习笔记】 网络编程之TCP
TCP 通信
服务端:
-
需要有一个地址及端口号
ServerSocket 类可以创建服务端套接字,它有四个构造方法
Constructor and Description |
---|
ServerSocket() 创建未绑定的服务器套接字。 |
ServerSocket(int port) 创建绑定到指定端口的服务器套接字。 |
ServerSocket(int port, int backlog) 创建服务器套接字并将其绑定到指定的本地端口号,并指定了积压。 |
ServerSocket(int port, int backlog, InetAddress bindAddr) 创建一个具有指定端口的服务器,侦听backlog和本地IP地址绑定。 |
其中backlog是指定消息队列的最大值,到达最大值后,服务端拒绝所有请求,直至队列中有新的位置
bindAddr:如果本机中有多个ip,我们可以使用这个参数来指定要绑定的ip地址
我们使用的是第二个,只传入一个端口号port,ip地址为默认地址
-
等待连接
Socket accept = serverSocket.accept();
调用serverSocket中的accept()方法,用来侦听连接到此套接字的请求,并接受,它返回的是Socket
-
读取客户端传来的消息
我们可以用流的方式来读取,注意当我们获取到消息时,不要直接读取,因为直接读的话,一旦某个字符超过了你所设定的缓冲数组的大小,那么他就从中间断开了,所输出的内容有可能就是乱码
这时,我们可以使用 管道流 (ByteArrayOutputStream),因为它是一个字节数组,也就是无论读还是写都是字节的读写,最后输出时,把字节给转成字符串即可。
-
关闭所有流
原则是:先开后关,首先关闭最后创建的流,原因是防止有数据没有传送完毕
代码:
package com.network.tcp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerDemo1 {
public static void main(String[] args) throws IOException {
//需要有一个地址
ServerSocket serverSocket = new ServerSocket(9999);
//等待连接
Socket accept = serverSocket.accept();
//读取客户端传来的消息
InputStream is = accept.getInputStream();
//通过管道流,给他输出
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = is.read(buffer)) != -1){
baos.write(buffer,0,count);
}
System.out.println(baos);
//关闭流
baos.close();
is.close();
accept.close();
serverSocket.close();
}
}
客户端:
-
知道服务器的地址和端口号
用 InetAddress 来表示IP地址
用 int 类型来表示端口号,该端口号就是服务端的端口号
-
创建Socket连接
Socket 该类实现客户端套接字
其中有一个构造方法:
Socket(InetAddress address, int port)
创建流套接字并将其连接到指定IP地址的指定端口号。
我们传入步骤1中的ip地址和端口号
-
发送消息
使用OutputStream传输消息
-
关闭所有流
原则是:先开后关,首先关闭最后创建的流,原因是防止有数据没有传送完毕
代码:
package com.network.tcp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpClinentDemo1 {
public static void main(String[] args) throws IOException {
//知道服务器的地址和端口号
InetAddress ipAddress = InetAddress.getByName("127.0.0.1");
int sort = 9999;
//创建socket连接
Socket socket = new Socket(ipAddress,sort);
//发送消息
OutputStream os = socket.getOutputStream();
os.write("好好学习,天天向上".getBytes());
//关闭
os.close();
socket.close();
}
}
TCP 实现文件上传
服务器:
-
创建服务器
ServerSocket serverSocket = new ServerSocket(9000); //穿入端口号
-
等待监听
Socket socket = serverSocket.accept();
-
获取输入流
InputStream is = socket.getInputStream();
-
获取文件
FileOutputStream fos = new FileOutputStream("f:\\test\\003.png");
byte[] buffer = new byte[1024];
int count;
while((count = is.read(buffer)) != -1){ //从输入流中读取文件到 buffer数组
fos.write(buffer,0,count); //把文件从buffer数组中写到硬盘
}
-
通知客户端,已经收到文件
OutputStream os = socket.OutputStream(); //获取输出流
os.write("我应经收到文件,可以断开连接了。".getBytes());
-
关闭所有流
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
客户端:
-
获取服务端的ip和端口号
Socket socket = new Socket(InetAdress.getByName(),9000);
-
获取输出流
OutputStream os = socket.getOutputStream();
-
输出文件
FileInputStream fis = new FileInputStream("f:\\test\\001.png");
byte[] buffer = new byte[1024];
int count;
while((count = fis.read()) != -1){ //从硬盘中读取文件到buffer数组
os.write(buffer,0,count); //从buffer数组写到/传输到服务端
}
-
告诉服务端,已经传完了
socket.shutdowmOutput(); //结束
-
接收服务端传来的消息
InputStream is =socket.getInputStream(); //获取输入流
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //创建输出流
byte[] buffer2 = new byte[1024];
int count2;
while((count2 = is.read(buffer2)) != -1){ //把从服务端传来的消息,读到buffer2中
baos.write(buffer2,0,count2); //把buffer2的内容,写到流中
}
System.out.prinln(baos); //打印流中的内容
-
关闭所有流
baos.close();
is.close();
fis.close();
os.close();
socket.close();
完整代码:
服务端:
package com.network.tcp;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServerDemo2 {
public static void main(String[] args) throws Exception {
//创建连接
ServerSocket serverSocket = new ServerSocket(9000);
//等待连接
Socket socket = serverSocket.accept();
//接收
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("f:\\test\\003.png");
byte[] buffer = new byte[1024];
int count = 0;
while ((count = is.read(buffer)) != -1){
fos.write(buffer,0,count);
}
//接受完毕后,向客户端发送消息
OutputStream os = socket.getOutputStream();
os.write("我接收完了,可以断开".getBytes());
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
客户端:
package com.network.tcp;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class TcpClinentDemo2 {
public static void main(String[] args) throws Exception {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("f:\\test\\001.png"));
byte[] buffer = new byte[1024];
int count = 0;
while((count = fis.read(buffer)) != -1){
os.write(buffer,0,count);
}
socket.shutdownOutput();
//接收服务端发来的消息
InputStream is = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer2 = new byte[1024];
int count2;
while ((count2 = is.read(buffer2)) != -1){
baos.write(buffer2,0,count2);
}
System.out.println(baos);
baos.close();
is.close();
fis.close();
os.close();
socket.close();
}
}