Socket编程(在控制台模拟聊天功能)
Posted fantongxue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket编程(在控制台模拟聊天功能)相关的知识,希望对你有一定的参考价值。
@
服务器端
(1) 创建ServerSocket对象,绑定监听端口;
(2) 通过accept()方法监听客户端请求;
(3) 连接建立后,通过输入流读取客户端发送的请求信息;
(4) 通过输出流向客户端发送相应信息;
(5) 关闭响应资源。
客户端
(1) 创建Socket对象,指明需要连接的服务器地址和端口;
(2) 连接建立后,通过输出流向服务器端发送请求信息;
(3) 通过输入流获取服务器端返回的响应信息;
(4) 关闭响应资源。
具体代码实现:
TCP简单示例
服务器:
public class SocketServerOne {
public static void main(String[] args) {
ServerSocket serverSocket = null;
Socket socket = null;
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
try {
//实例化ServerSocket
serverSocket=new ServerSocket(8888);
//调用accept方法,启动监听,该方法在客户端发送信息之前,一直阻塞(一直等待)
System.out.println("服务器端已经启动。。。");
socket = serverSocket.accept();
//服务器接收信息
//返回此套接字的输入流,输入流里面放的就是客户端发送过来的信息
//InputStreamReader的作用把字节流转换为字符流
//BufferedReader套接缓冲流,目的用来提高读写效率
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//调用readLine()方法得到字符串
String s = bufferedReader.readLine();
//打印
System.out.println("客户端说:"+s);
//服务器发送信息
printWriter = new PrintWriter(socket.getOutputStream());
printWriter.println("你好客户端,你发送的信息我收到了");
//清空管道
printWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
bufferedReader.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端:
public class SocketClientOne {
public static void main(String[] args) {
Socket socket=null;
PrintWriter printWriter = null;
try {
//实例化Socket对象,通过链接的IP和端口号进行实例化
socket=new Socket("127.0.0.1",8888);
//客户端发送信息
//通过PrintWriter向套接字输出流里面写入信息
printWriter = new PrintWriter(socket.getOutputStream());
//调用printLine方法写入信息
printWriter.println("你好,服务器22");
//刷新管道
printWriter.flush();
System.out.println("信息发送完毕。。。");
//客户端接收信息
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//调用readLine方法得到字符串
String s=bufferedReader.readLine();
//打印
System.out.println("服务器端说:"+s);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
printWriter.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
TCP模拟聊天
服务器:
public class SocketServerTwo {
public static void main(String[] args) {
ServerSocket serverSocket=null;
Socket socket = null;
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
try {
serverSocket=new ServerSocket(7777);
System.out.println("服务器启动。。。");
//启动监听
socket = serverSocket.accept();
//接收相关方法
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//发送的相关的方法
printWriter = new PrintWriter(socket.getOutputStream());
//控制台扫描类
Scanner scanner=new Scanner(System.in);
//循环接收信息或者扫描控制台发送信息
while(true){
//读取
String s = bufferedReader.readLine();
System.out.println("客户端说:"+s);
if(s.contains("借钱")){
printWriter.println("你被拉入黑名单。。");
printWriter.flush();
break;
}
System.out.println("请输入:");
String next = scanner.next();
//发送
printWriter.println(next);
//清空
printWriter.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
printWriter.close();
bufferedReader.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端:
public class SocketClientTwo {
public static void main(String[] args) {
Socket socket=null;
BufferedReader bufferedReader = null;
PrintWriter printWriter = null;
try {
socket=new Socket("127.0.0.1",7777);
//接收相关方法
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//发送的相关的方法
printWriter = new PrintWriter(socket.getOutputStream());
//控制台扫描类
Scanner scanner=new Scanner(System.in);
//循环
while(true){
System.out.println("请输入:");
//发送
String next = scanner.next();
printWriter.println(next);
printWriter.flush();
//接收
String s = bufferedReader.readLine();
System.out.println("服务器说:"+s);
if(s.contains("黑名单")){
printWriter.println("借钱");
printWriter.flush();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
printWriter.close();
bufferedReader.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
UDP简单示例
UDP程序原理
客户端:
1) 创建客户端 DatagramSocket 类 + 指定的发送端口
2) 准备数据 以字节数组的形式
3) 打包 DatagramPacket+服务器端的地址和端口
4) 发送
5) 释放资源
服务器端
1) 创建服务端 DatagramSocket 类 + 指定的接收端口
2) 准备接收数据的容器 以字节数组的形式封装为DatagramPacket
3) 包 接收数据
4) 分析
5) 释放资源
服务器端:
public class UDPServer {
public static void main(String[] args) {
DatagramSocket datagramSocket=null;
try {
//实例化DatagramSocket用于发送或者接收数据
datagramSocket=new DatagramSocket();
//声明发送字符串
String str="hello qy88";
//实例化数据报包类,数据的载体
DatagramPacket datagramPacket=new DatagramPacket(str.getBytes(),str.getBytes().length,
InetAddress.getByName("localhost"),6666);
//发送
datagramSocket.send(datagramPacket);
System.out.println("发送完毕。。。");
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
datagramSocket.close();
}
}
}
客户端:
public class UDPClient {
public static void main(String[] args) {
DatagramSocket datagramSocket=null;
try {
datagramSocket=new DatagramSocket(6666);
byte[] by=new byte[1024];
//数据的载体,会把接收到的数据放入缓冲数组,并且记录下放入数组的长度
DatagramPacket datagramPacket=new DatagramPacket(by,1024);
System.out.println("接收端已经启动。。。");
//接收
datagramSocket.receive(datagramPacket);
//组装数据,打印
String str=new String(by,0,datagramPacket.getLength());
System.out.println(str);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP模拟聊天
服务端
package com.qq.common;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Scanner;
public class ServerThread implements Runnable {
private int port;
public ServerThread(int port) {
super();
this.port=port;
}
@Override
public void run() {
@SuppressWarnings("resource")
Scanner scanner=new Scanner(System.in);
//服务端(接收方)的端口
DatagramSocket ds = null;
try {
ds = new DatagramSocket(port);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("服务端已经启动!");
while(true) {
//准备收数据
byte[] b=new byte[1024];
DatagramPacket dp=new DatagramPacket(b, b.length);
//开始收 收到的是字节数组
try {
ds.receive(dp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(new String(dp.getData(),0,dp.getLength()));
System.out.println("对方IP地址:"+dp.getAddress()+" "+"端口:"+dp.getPort());
//发数据
//准备数据
String s=scanner.next();
byte[] buf=s.getBytes();
//打包
DatagramPacket dp2=new DatagramPacket(buf, buf.length,dp.getAddress(),dp.getPort());
try {
ds.send(dp2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if("bye".equals(s)) {
break;
}
}
ds.close();
}
}
package com.qq.common;
public class Test {
public static void main(String[] args) {
ServerThread server=new ServerThread(8886);
Thread thread=new Thread(server);
thread.start();
}
}
客户端
package common;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientThread implements Runnable{
private int port;
public ClientThread(int port) {
this.port=port;
}
@Override
public void run() {
@SuppressWarnings("resource")
Scanner scanner=new Scanner(System.in);
//发数据
DatagramSocket ds = null;
try {
ds = new DatagramSocket(9999);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//客户端的端口号是9999
System.out.println("客户端已经启动,开始聊天吧?!");
while(true) {
String s=scanner.next();
byte[] buf=s.getBytes();
DatagramPacket dp = null;
try {
dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),port);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
ds.send(dp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buf2=new byte[1024];
DatagramPacket dp2=new DatagramPacket(buf2, buf2.length);
try {
ds.receive(dp2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("对方IP地址:"+dp2.getAddress()+" "+"端口:"+dp2.getPort());
String str=new String(dp2.getData(),0,dp2.getLength());
System.out.println(str);
if("bye".equals(str)) {
break;
}
}
ds.close();
}
}
package common;
public class Test {
public static void main(String[] args) {
ClientThread client=new ClientThread(8886);
Thread t=new Thread(client);
t.start();
}
}
TCP和UDP是Java网络编程中的传输方式。TCP提供两台计算机之间可靠无差错的数据传输,但资源消耗较大,性能和效率较低;UDP不保证可靠数据的传输,但资源消耗小,性能和效率较高。在实际网络编程中建议根据系统的特点和需要,具体选择合适的方式
以上是关于Socket编程(在控制台模拟聊天功能)的主要内容,如果未能解决你的问题,请参考以下文章