一、好久没写网络编程代码,今天有空,复习一下。下面主要实现服务器端和客户端端通信,服务器端接受一个客户端就启动一个新线程处理,读写也用线程实现,其中读,一个只读10个字节,循环读取输入流。好,废话少说,上代码。
1、服务器端:
package com.ppt.socket;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 服务端
*/
public class Server {
private int port = 9999;
private ServerSocket server;
private static Socket socket;
public Server() {
try {
init();
} catch(Exception e) {
e.printStackTrace();
}
}
private void init() throws Exception {
server = new ServerSocket(port);
System.out.println("server socket is start, port is: " + port);
while(true) {
socket = server.accept();
handle(socket);
}
}
private void handle(Socket socket) throws Exception {
String key = socket.getInetAddress().getHostAddress()+":"+socket.getPort();
System.out.println("accept a socket: " + key);
Thread thread = new Thread(new ThreadSocket(socket));
thread.start();
}
public static void main(String[] args) throws Exception {
Server server = new Server();
}
}
2、客户端:
package com.ppt.socket;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
/**
* 客户端
* @author aa
*
*/
public class Client {
private String ip = "127.0.0.1";
private int port = 9999;
private static Socket socket;
public Client() {
try {
init();
} catch(Exception e) {
e.printStackTrace();
}
}
private void init() throws Exception {
System.out.println("init the socket client");
socket = new Socket();
socket.setSoTimeout(0);
SocketAddress addr = new InetSocketAddress(ip, port);
socket.connect(addr);
}
public void handle() throws Exception{
Thread threadRead = new Thread(new ThreadRead(socket.getInputStream()),"SERVER_"+socket.getPort());
Thread threadwrite = new Thread(new ThreadWrite(socket.getOutputStream()));
threadRead.start();
threadwrite.start();
}
public static void main(String[] args) throws Exception {
Client client = new Client();
client.handle();
}
}
3、服务器处理socket线程:
package com.ppt.socket;
import java.net.Socket;
/**
* 一个socket,一个线程
* @author aa
*
*/
public class ThreadSocket implements Runnable {
private Socket socket;
public ThreadSocket(Socket socket) {
this.socket = socket;
}
public void run() {
try {
Thread threadRead = new Thread(new ThreadRead(socket.getInputStream()),"CLIENT_"+socket.getPort());
Thread threadwrite = new Thread(new ThreadWrite(socket.getOutputStream()));
threadRead.start();
threadwrite.start();
} catch(Exception e) {
e.printStackTrace();
}
}
}
4、读取输入流线程:
package com.ppt.socket;
import java.io.InputStream;
public class ThreadRead implements Runnable {
private static int HEAD_SIZE = 5;//传输最大字节长度--99999
private static int BUFFER_SIZE = 10;//每次读取10个字节,循环读取输入流--测试,所以读10个字节
private InputStream is;
public ThreadRead(InputStream is) {
this.is = is;
}
public void run() {
try {
while(true) {
boolean flag = true;
int msgLength = 0;
int recvSize = -HEAD_SIZE;
byte[] buf = new byte[BUFFER_SIZE];
StringBuffer sb = new StringBuffer();
while(msgLength > recvSize) {
int length = is.read(buf,0,BUFFER_SIZE);
recvSize += length;
if(flag) {
String str = new String(buf,0,HEAD_SIZE);
msgLength = Integer.parseInt(str);
sb.append(new String(buf,HEAD_SIZE,length-HEAD_SIZE));
flag = false;
} else {
sb.append(new String(buf,0,length));
}
}
System.out.println(Thread.currentThread().getName() +": "+ sb.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
5、发送数据线程:
package com.ppt.socket;
import java.io.OutputStream;
import java.util.Scanner;
public class ThreadWrite implements Runnable {
private static int HEAD_SIZE = 5;//传输最大字节长度--99999
private OutputStream os;
public ThreadWrite(OutputStream os) {
this.os = os;
}
public void run() {
try {
Scanner scan = new Scanner(System.in);
while(true) {
String sendMsg = scan.next();
sendMsg = getMsg(sendMsg);
os.write(sendMsg.getBytes());
os.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param msg--组转发送字符串,首五个字符是字符串长度,不够五位,用0补足
* @return
*/
private static String getMsg(String msg) {
int length = String.valueOf(msg.length()).length();
String slen = "";
if(length < HEAD_SIZE) {
StringBuffer sb = new StringBuffer();
for(int i=0; i<HEAD_SIZE-length; i++) {
sb.append("0");
}
sb.append(String.valueOf(msg.length()));
return sb.toString()+msg;
} else {
slen = String.valueOf(length);
}
return slen+msg;
}
}
6、至此,一个简单的多线程socket通信就完成了,够简单吧。