本文描述了计算机网络实验4 - TCP套接字编程 - 点对点聊天 - 代码实现的相关知识,对类似的源码问题比较有借鉴作用,感兴趣的可以了解细看。
客户端
package chat;
import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
class ClientReadServer implements Runnable{
private Socket socket;
public ClientReadServer(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
Scanner scanner=new Scanner(socket.getInputStream());
System.out.println("test");
while(scanner.hasNext()){
String meg=scanner.nextLine();
System.out.println("服务端返回:"+meg);
Frame.back(meg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientSendServer implements Runnable{
private static boolean sendFlag = false;
private static String msg;
private Socket socket;
public ClientSendServer(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
PrintStream printStream=new PrintStream(socket.getOutputStream());
while(true){
if(sendFlag){
printStream.println(msg);
System.out.println("线程中run 发送:"+msg);
sendFlag = false;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void change(String m,boolean b) {
msg = m;
sendFlag = true;
}
}
public class Client {
public void mainClient () throws IOException{
Socket socket=new Socket("127.0.0.1",9527);
Thread read=new Thread(new ClientReadServer(socket));
Thread send=new Thread(new ClientSendServer(socket));
read.start();
send.start();
}
public void send(String mes) {
System.out.println("准备发送的数据:"+mes);
ClientSendServer.change(mes, true);
}
}
用户界面
package chat;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.swing.*;
public class Frame extends JFrame {
private static Client client;
private static String backMeg = "";
private static JTextArea area;
private static final long serialVersionUID = 1L;
public static void back(String m) {
backMeg = m;
if(backMeg.contains(":")) {
String context = backMeg;
String name ="\n"+ backMeg.split("@")[1].split("\\:")[0] + ":";
context=context.replace('@','\n');
context=context.replace("$",name);
area.append(context+"\n");
}
}
public Frame() {
setTitle("ChatRoom");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(200, 200, 650, 600);
setResizable(false);
Container c = getContentPane();
c.setBackground(new Color(255, 221, 221,200));
c.setLayout(null);
Font f1=new Font("黑体",Font.PLAIN,16);
Font f2=new Font("楷体",Font.BOLD,18);
Font f4=new Font("楷体",Font.BOLD,16);
Font f3=new Font("黑体",Font.PLAIN,14);
JTextArea jt = new JTextArea();
jt.setFont(f4);
JScrollPane jp = new JScrollPane(jt);
jp.setBounds(50, 490, 420, 40);
c.add(jp);
area = new JTextArea();
area.setFont(f2);
area.setEditable(false);
JScrollPane jpArea = new JScrollPane(area);
jpArea.setBounds(50, 190, 510, 250);
c.add(jpArea);
JLabel message = new JLabel();
message.setFont(f2);
message.setText("接收消息区");
message.setBounds(50, 125, 140, 80);
c.add(message);
JLabel sendmessage = new JLabel();
sendmessage.setFont(f2);
sendmessage.setText("在此输入您要发送的消息,点击右侧发送按钮发送");
sendmessage.setBounds(50, 430, 500, 80);
c.add(sendmessage);
JLabel desIp = new JLabel();
desIp.setFont(f2);
desIp.setText("目标IP:");
desIp.setBounds(50, 20, 100, 80);
c.add(desIp);
JTextField desjt = new JTextField();
desjt.setFont(f4);
desjt.setBounds(140, 45, 150, 30);
desjt.setText("127.0.0.1");
desjt.setEditable(false);
c.add(desjt);
JLabel desPo = new JLabel();
desPo.setFont(f2);
desPo.setText("目标端口:");
desPo.setBounds(320, 20, 100, 80);
c.add(desPo);
JTextField desJtPo = new JTextField();
desJtPo.setFont(f4);
desJtPo.setBounds(405, 45, 150, 30);
desJtPo.setText("0000");
c.add(desJtPo);
JLabel name = new JLabel();
name.setFont(f2);
name.setText("你的昵称:");
name.setBounds(50, 75, 100, 80);
c.add(name);
JTextField jtName = new JTextField();
jtName.setFont(f4);
jtName.setBounds(140, 100, 150, 30);
int num = (int) (Math.random()*100);
String t = "未命名用户["+num+"]";
jtName.setText(t);
c.add(jtName);
JLabel myPo = new JLabel();
myPo.setFont(f2);
myPo.setText("本机端口:");
myPo.setBounds(320, 75, 100, 80);
c.add(myPo);
JTextField jtmyPo = new JTextField();
jtmyPo.setFont(f4);
jtmyPo.setBounds(405, 100, 150, 30);
jtmyPo.setEditable(false);
c.add(jtmyPo);
JButton btnBind = new JButton("绑定端口 建立连接");
btnBind.setBackground(new Color(255,221,221));
btnBind.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try {
client.mainClient();
client.send("userName:"+jtName.getText());
} catch (IOException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("***"+backMeg);
jtmyPo.setText(backMeg);
}
});
btnBind.setBounds(405, 130, 150, 30);
btnBind.setFont(f3);
c.add(btnBind);
JButton btn = new JButton("发送");
btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String context = jt.getText().equals("")?"空空如也":jt.getText();
context=context.replace('\n','$');
jt.setText("");
jt.requestFocus();
String sendPort = desJtPo.getText();
if(sendPort.equals("")) return;
String name = jtName.getText();
String sendMes = "P:" + sendPort +"-"+ name + "-" + context;
System.out.println("发送框中的内容是:"+sendMes);
client.send(sendMes);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
});
btn.setBounds(490, 490, 70, 40);
btn.setBackground(new Color(255,221,221));
btn.setFont(f1);
c.add(btn);
setVisible(true);
}
public static void beautiful() {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}catch(Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
beautiful();
client = new Client();
new Frame();
}
}
服务器端
package chat;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Server implements Runnable{
private static Map<String,Socket> map=new ConcurrentHashMap<>();
private Socket socket;
public Server(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
Scanner scanner=new Scanner(socket.getInputStream());
String msg=null;
while(true){
if(scanner.hasNextLine()){
msg=scanner.next();
System.out.println("服务器接收:"+msg);
if(msg.startsWith("userName:")){
String userName=msg.split("\\:")[1];
userRegist(userName,socket);
continue;
}
else if(msg.startsWith("P:")&&msg.contains("-")){
String port=msg.split("\\:")[1].split("-")[0];
String name = msg.split("\\:")[1].split("-")[1];
String str=msg.split("\\:")[1].split("-")[2];
privateChat(port,name,str);
continue;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void userRegist(String userName,Socket socket) throws IOException{
PrintStream printStream=new PrintStream(socket.getOutputStream());
String port=socket.toString().split(",")[1].split("=")[1];
printStream.println(port);
map.put(port,socket);
System.out.println("[用户名为"+userName+"][客户端为"+socket+"]上线了!");
System.out.println("当前在线人数为:"+map.size()+"人");
}
private void privateChat(String port,String userName,String msg) throws IOException {
String curUser=userName;
Socket client=map.get(port);
PrintStream printStream=new PrintStream(client.getOutputStream());
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String m = formatter.format(date)+"@"+curUser+":"+msg;
System.out.println(formatter.format(date));
System.out.println(m);
printStream.println(m);
}
}
public class MultiServer {
public static void main(String[] args){
try {
ServerSocket serverSocket=new ServerSocket(9527);
ExecutorService executorService= Executors.newFixedThreadPool(50);
for(int i=0;i<50;i++){
System.out.println("欢迎来到我的聊天室......");
Socket socket=serverSocket.accept();
System.out.println("有新的朋友加入.....");
executorService.execute(new Server(socket));
}
executorService.shutdown();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
详细解析在另一篇给出:
[计算机网络实验4 - TCP套接字编程 - 点对点聊天 - 分析] - 找不到我吧我独一无二的博客 - CSDN博客
关键词:socket
java
网络
多线程,计算,计算机,计算机网,计算机网络,网络,实验,tcp,套接字,编程,点对点,聊天,代码,实现