TCP:客户端和服务端连接用socket套接字,传输数据时,用输出流输出(OutputStream)。
客户端
public class TcpClientDemo1 {
public static void main(String[] args) {
OutputStream outputStream = null;
try {
//1、要知道服务端的地址
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
int port = 9999;
//创建一个socket连接
Socket socket = new Socket(inetAddress,port);
//发送消息
outputStream = socket.getOutputStream();
outputStream.write("欢迎学习".getBytes());
outputStream.flush();
?
} catch (Exception e) {
e.printStackTrace();
}finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
?
?
?
}
}
服务端
public class TcpServerDemo1 {
public static void main(String[] args) {
//1、服务端需要一个地址
ServerSocket serverSocket = null;
InputStream inputStream = null;
Socket socket = null;
ByteArrayOutputStream byteArrayOutputStream = null;
?
try {
serverSocket = new ServerSocket(9999);
//接收
socket = serverSocket.accept();
//读取客户端的消息
inputStream = socket.getInputStream();
?
// byte[] bytes = new byte[1024];
// int len;
// while ((len = inputStream.read(bytes)) != -1){
// System.out.println(new String(bytes,0,len));
// }
//管道流
byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len=inputStream.read(bytes))!= -1){
byteArrayOutputStream.write(bytes,0,len);
}
System.out.println(byteArrayOutputStream.toString());
?
} catch (IOException e) {
e.printStackTrace();
}finally {
if (byteArrayOutputStream != null) {
try {
byteArrayOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
?
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
?
}
}
}
客户端
public class TcpClientDemo02 {
public static void main(String[] args) throws Exception {
//上传文件,用Socket连接
//Socket连接需要传服务端的IP和端口
Socket socket = new Socket(InetAddress.getByName("localhost"),8888);
// DatagramSocket socket = new DatagramSocket(8888); //自己端口号位8888
?
//将数据打包成一个包裹
byte[] bytes = new byte[1024];
//上传一个文件,将文件读出来
FileInputStream fis = new FileInputStream("网络编程/meitu.jpg");//使用相对路径
//IO流的老一套
int len;
//上传文件,不需要打包,直接用输出流
OutputStream os = socket.getOutputStream();
while ((len=fis.read(bytes)) != -1){
os.write(bytes,0,len);
}
os.flush();
//
// DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);//包裹要求数据必须为byte数组形式,需要服务端的IP还有端口号
//
// //将数据传送给服务端
// socket.send();
?
fis.close();
os.close();
socket.close();
}
}
服务端
public class TcpServerDemo02 {
public static void main(String[] args) throws Exception {
//创建一个端口为8888的socket连接的服务端
ServerSocket serverSocket = new ServerSocket(8888);
?
//监听连接
Socket socket = serverSocket.accept();
?
//创建输入流,接收客户端输出流的数据
InputStream is = socket.getInputStream();
//使用管道流来将读出的数据加载到服务端硬盘中
FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
//IO流一套
byte[] bytes = new byte[1024];
int len;
while ((len=is.read(bytes))!=-1){
fos.write(bytes,0,len);
}
?
fos.close();
is.close();
socket.close();
serverSocket.close();
?
}
}
小结
1、使用TCP模式,不管是客户端还是服务端,在写数据时都用管道流进行输出。
问题:如何让服务端给客户端发送信息?
聊天对话的传输端
public class TalkClient implements Runnable {
DatagramSocket socket = null;
BufferedReader reader = null;
?
private String toIP;
private int fromPort;
private int toPort;
?
public TalkClient( int fromPort, int toPort,String toIP) {
this.toIP = toIP;
this.fromPort = fromPort;
this.toPort = toPort;
try {
socket = new DatagramSocket(this.fromPort);
reader = new BufferedReader(new InputStreamReader(System.in));
} catch (SocketException e) {
e.printStackTrace();
}
?
}
?
接收端
public class TalkReceive implements Runnable{
DatagramSocket socket = null;
?
private int port;
private String msgFrom;
?
public TalkReceive(int port,String msgFrom) {
this.port = port;
this.msgFrom = msgFrom;
?
try {
socket = new DatagramSocket(port);
} catch (SocketException e) {
e.printStackTrace();
}
}
?
学生
public class TalkStudent {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkClient(7777,9999,"localhost")).start();
new Thread(new TalkReceive(8888,"老师")).start();
}
?
}
老师
public class TalkTeacher {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkClient(6666,8888,"localhost")).start();
new Thread(new TalkReceive(9999,"学生")).start();
}
}
小结
学生和老师,都同时拥有接收端和发送端,所以要分别为其分配不同的端口号。
原文:https://www.cnblogs.com/lee-leo/p/12996727.html