您的位置:首页 > 编程语言

多线程socket编程--聊天程序

2015-09-20 11:27 507 查看
一、好久没写网络编程代码,今天有空,复习一下。下面主要实现服务器端和客户端端通信,服务器端接受一个客户端就启动一个新线程处理,读写也用线程实现,其中读,一个只读10个字节,循环读取输入流。好,废话少说,上代码。

1、服务器端:

[java]
view plaincopyprint?





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();  
    }  
}  

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、客户端:

[java]
view plaincopyprint?





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();  
    }  
  
}  

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线程:

[java]
view plaincopyprint?





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();  
        }  
    }  
}  

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、读取输入流线程:

[java]
view plaincopyprint?





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();  
        }  
          
    }  
}  

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、发送数据线程:

[java]
view plaincopyprint?





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;  
    }  
}  

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通信就完成了,够简单吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: