TCP
- TCP是一种网络传输层协议,它传输的可靠性高,需要连接,但是效率较慢,只能实现一对一。
- 因为TCP需要建立连接,所以需要用ServerSocket 和 Socket 来连接,ServerSocket里面有一个accept方法,可以监听到连接的socket,当accept连接成功之后,就可以互相发送数据。
- Socket类中有两个方法可以获得输入和输出流,通过他们可以发送和接收数据报:
获得输入流: public InputStream getInputStream() throws IOException
获得输出流:public OutputStream getOutputStream() throws IOException
以下举一个ServerSocket的例子,可以实现双相连接
Server类
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server1 {
private int port = 8080;
private Button b1;//send
private Button b3;//connect
private Button b4;//exit
private TextArea area;//用户列表
private TextArea area1;//聊天记录
private ServerSocket socket;//服务器端
private TextField f1;//IP
private TextField f2;//port
private TextField f3;//userName
private TextField f4;//发送行
private Frame window;//窗口
private Label l1;//IP
private Label l2;//port
private Label l3;//username
private Label l4;//list of users
private Socket socket1;//接收到的socket
public static void main(String[] args) throws IOException {
Server1 server = new Server1();
server.talk();
}
private void talk() throws IOException {
socket = new ServerSocket(port);
window = new Frame("服务器");
window.setLayout(null);
window.setBounds(200, 200, 500, 400);
window.setResizable(false);
l1 = new Label("IP");
l1.setBounds(10, 25, 20, 30);
window.add(l1);
f1 = new TextField();
f1.setBounds(35, 30, 80, 25);
f1.setEditable(false);
window.add(f1);
l2 = new Label("port");
l2.setBounds(125, 25, 30, 30);
window.add(l2);
f2 = new TextField();
f2.setBounds(160, 30, 40, 25);
f2.setEditable(false);
window.add(f2);
l3 = new Label("userName");
l3.setBounds(205, 25, 60, 30);
window.add(l3);
f3 = new TextField();
f3.setBounds(275, 30, 80, 25);
f3.setEditable(false);
window.add(f3);
b3 = new Button("connect");
b3.setBounds(365, 30, 60, 25);
window.add(b3);
b4 = new Button("exit");
b4.setBounds(435, 30, 60, 25);
window.add(b4);
l4 = new Label("list of users");
l4.setBounds(30, 50, 80, 25);
window.add(l4);
area1 = new TextArea();
area1.setBounds(10, 80, 120, 250);
area1.setEditable(false);
window.add(area1);
area = new TextArea("聊天记录\n");
area.append("---------------------------------------------------------------------------------\n");
area.setBounds(130, 80, 350, 250);
area.setEditable(false);
window.add(area);
f4 = new TextField();
f4.setBounds(10, 340, 380, 40);
window.add(f4);
b1 = new Button("send");
Font font = new Font("宋体", Font.PLAIN, 20);
b1.setFont(font);
b1.setBounds(400, 340, 60, 40);
window.add(b1);
listen();
window.setVisible(true);
}
private void receive() throws IOException {
DataInputStream input = new DataInputStream(socket1.getInputStream());
String msg = input.readUTF();
area.append(msg + "\n");
}
private void listen() {
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
b4.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
receive();
} catch (IOException ex) {
ex.printStackTrace();
}
sendMSG();
}
});
b3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
socket1 = socket.accept();
DataOutputStream output = new DataOutputStream(socket1.getOutputStream());
output.writeUTF("hello");
output.flush();
InetAddress ip = socket1.getInetAddress();
f1.setText(ip.getHostAddress());
f2.setText(socket1.getPort() + "");
f3.setText(ip.getHostName());
area1.setText(ip.getHostName());
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
window.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER){
sendMSG();
}
}
});
}
private void sendMSG() {
try {
DataOutputStream out = new DataOutputStream(socket1.getOutputStream());
String context = f4.getText();
out.writeUTF(context);
out.flush();
area.append(f4.getText() + "\n");
f4.setText(null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Client类
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.Socket;
public class Client1 {
private String host = "localhost";
private int port = 8080;
private Frame window;
TextArea area;
Button b1;
Button b2;
TextField field;
Socket socket;
DataInputStream inputStream;
DataOutputStream outputStream;
public static void main(String[] args) throws IOException, InterruptedException {
Client1 client = new Client1();
client.talk();
}
private void talk() throws IOException, InterruptedException {
window = new Frame("客户端");
window.setLayout(null);
window.setBounds(200, 200, 500, 400);
window.setResizable(false);
area = new TextArea();
area.setBounds(30, 30, 400, 280);
area.setEditable(false);
window.add(area);
b1 = new Button("send");
b1.setBounds(300, 360, 40, 30);
window.add(b1);
b2 = new Button("exit");
b2.setBounds(380, 360, 40, 30);
window.add(b2);
field = new TextField();
field.setBounds(20, 320, 450, 30);
window.add(field);
window.setVisible(true);
socket = new Socket(host, port);
inputStream = new DataInputStream(socket.getInputStream());
String s = inputStream.readUTF();
area.append(s + "\n");
listen();
}
private void senMsg() {
try {
outputStream = new DataOutputStream(socket.getOutputStream());
String context = field.getText();
outputStream.writeUTF(context);
outputStream.flush();
area.append(field.getText() + "\n");
field.setText(null);
} catch (IOException e) {
e.printStackTrace();
}
}
private void receive() throws IOException {
inputStream = new DataInputStream(socket.getInputStream());
String s = inputStream.readUTF();
area.append(s + "\n");
}
private void listen() {
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
window.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
senMsg();
try {
receive();
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
field.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
senMsg();
try {
receive();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
});
}
}
客户端运行窗口是这样的
服务器端运行窗口: