TCP通信
tcp客户端tcp服务器端测试服务器端多线程实现
实现一个远程调用词典翻译的例程,题目如下:
传输层的TCP协议通过三报文握手建立连接,四报文挥手关闭连接。TCP协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。
Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信Java为客户端提供了Socket类,为服务器端提供了ServerSocket类。
package socket.socTcp;
import java.net.*;
import java.io.*;
//客户端程序
public class Client {
private InetAddress addr; // 存储ip地址
private Socket socket; // 客户端套接字
//创建Socket
Client(String s) throws Exception {
addr=InetAddress.getByName(s); // 获取本地ip地址
}
// 根据端口创建连接
public void connect(int port)throws Exception{
//建立连接
socket = new Socket(addr,port);
InputStreamReader Sysin = new InputStreamReader(System.in);
BufferedReader SysBuf = new BufferedReader(Sysin);
InputStreamReader Socin = new InputStreamReader(socket.getInputStream());
BufferedReader SocBuf = new BufferedReader(Socin);
PrintWriter Socout = new PrintWriter(socket.getOutputStream());
//进行通信
String readline = SysBuf.readLine();
int k=0;
while(true){
Socout.println(readline);
Socout.flush(); // 刷新
System.out.println(SocBuf.readLine());
if(readline.equals("bye")){
k=1;
System.out.println("如果你想退出,请再次输入“bye”,否则,该连接不会终止!");
}
readline = SysBuf.readLine();
if(readline.equals("bye")&&k==1){
// 退出前告知服务器终止连接
Socout.println(readline);
Socout.flush(); // 刷新
break;
}
else k=0;
}
//关闭IO和Socket
Socout.close();
Socin.close();
}
public void finall()throws Exception{
socket.close();
}
public static void main(String[] args){
try{
Client client=new Client("localhost");
client.connect(10001);
client.finall();
}catch(Exception e){
System.out.println("Error:" + e);
}
}
}
tcp服务器端
package socket.socTcp;
import java.net.*;
import java.io.*;
import java.util.*;
//服务器程序
public class Server {
ServerSocket server; // 服务器端套接字
private HashMap dic;// 词典
Server(){
initDic();
}
// 初始化词典,我这里随便写了个词典,只是为了测试程序
private void initDic() {
dic = new HashMap<>();
dic.put("中国", "China");
dic.put("苹果", "apple");
dic.put("拜拜", "bye");
}
// 根据输入在词典中查找翻译结果,如果没有找到返回null
public String translate(String read) {
String res = dic.getOrDefault(read, null);
// 如果key中找不到,则在value中查找
if(res==null){
for(String key: dic.keySet()){
if(dic.get(key).equals(read)){
res = key;
}
}
}
return res;
}
// 建立连接
public void connect(int port) throws Exception{
server = new ServerSocket(port);
Socket socket = server.accept();
InputStreamReader Socin = new InputStreamReader(socket.getInputStream());
BufferedReader SocBuf = new BufferedReader(Socin);
PrintWriter Socout = new PrintWriter(socket.getOutputStream());
//通信
String readline = SocBuf.readLine();
String re;
System.out.println("这里是服务器,我们已与您建立连接!");
int k=0;
while(true){
re=translate(readline);
Socout.println(readline+"的翻译结果是:"+re);
Socout.flush();
if(readline.equals("bye")){
k=1;
}
readline = SocBuf.readLine();
if(readline.equals("bye")&&k==1) break;
else k=0;
}
//关闭IO、Socket
Socout.close();
Socin.close();
}
public void finall()throws Exception{
server.close();
}
public static void main(String[] args){
try{
Server ser=new Server();
ser.connect(10001);
ser.finall();
}catch (Exception e){
System.out.println("Error" + e);
}
}
}
先启动服务器端,再启动客户端。
测试客户端界面:
hu hu的翻译结果是:null china china的翻译结果是:null China China的翻译结果是:中国 拜拜 拜拜的翻译结果是:bye bye bye的翻译结果是:拜拜 如果你想退出,请再次输入“bye”,否则,该连接不会终止! apple apple的翻译结果是:苹果 苹果 苹果的翻译结果是:apple bye bye的翻译结果是:拜拜 如果你想退出,请再次输入“bye”,否则,该连接不会终止! bye Process finished with exit code 0
服务器端界面:
这里是服务器,我们已与您建立连接! Process finished with exit code 0服务器端多线程实现
仅修改服务器端的程序即可,客户端程序不变。
package socket.socThread;
import java.io.*;
import java.net.*;
public class ServerThread implements Runnable {
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
//接收数据写入文本文件
try {
//解决名称冲突
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
int count = 0;
File file = new File("E:\out\data["+count+"].txt");
while (file.exists()) {
count++;
file = new File("E:\out\data["+count+"].txt");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
BufferedWriter bwServer = new BufferedWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())));
String line=br.readLine();
int k=0;
while(true) {
String trans=new Translator().translate(line);
bwServer.write(line+"的翻译结果是:"+trans);
bwServer.newline();
bwServer.flush();
bw.write(line);
bw.newline();
bw.flush();
if(line.equals("bye")){
k=1;
}
line=br.readLine();
if(line.equals("bye")&&k==1) break;
else k=0;
}
s.close();
System.out.println("线程"+count+"已退出!");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
//创建服务器Socket对象
ServerSocket ss = new ServerSocket(10001);
Socket s;
//监听客户端连接
while(true) {
s = ss.accept();
//为每一个客户端开启一个线程
new Thread(new ServerThread(s)).start();
}
}
}



