使用Java进行网络编程,通常会用到TCP,UDP协议。TCP是面向连接的,是可靠的传输层协议;UDP是无连接的,但是效率更高。下面是一个简单的使用Socket写的一个小例子用来实现TCP协议通信。
Server.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @description:服务器端
* @date:(2015-9-13 下午8:41:06)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
//监听端口
int port=8090;
//服务器端监听8090端口
ServerSocket serverSocket=new ServerSocket(port);
//服务器端监听客户端的连接请求,accept方法是阻塞式的
Socket socket=serverSocket.accept();
/**
* 服务端从Socket的InputStream中读
* 取数据的操作也是阻塞式的,如果从输入
* 流中没有读取到数据程序会一直在那
* 里不动,直到客户端往Socket的输出流中写入了数据,或关闭了Socket的输出流。
* 客户端的Socket也是同样如此
* */
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
StringBuffer sb=new StringBuffer();
String temp=null;
int index;
while((temp=reader.readLine())!=null){
//不设置结束符,可能输入流会
if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收
sb.append(temp.substring(0, index));
break;
}
sb.append(temp);
}
System.out.println("receive from client:"+sb.toString());
//输出信息到客户端
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
//读取控制台输入
BufferedReader bufReader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("server say:");
writer.write(bufReader.readLine());
writer.write("hello client");
/**
* BufferedReader的readLine方法是一次读一行的,
* 这个方法是阻塞的,直到它读到了一行数据为止程序才会继续往下执行,
* 那么readLine什么时候才会读到一行呢?直到程序遇到了换行符或者是对应流的
* 结束符readLine方法才会认为读到了一行,才会结束其阻塞,让程序继续往下执行。
* 所以我们在使用BufferedReader的readLine读取数据的时候一定要记得在对应的输出流里面一定要写入换行符
* */
writer.write("eof\n");//设置结束符
writer.flush();
writer.close();
bufReader.close();
reader.close();
socket.close();
serverSocket.close();
}
}
Client.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* @description:客户端
* @date:(2015-9-13 下午8:48:49)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class Client {
public static void main(String[] args) throws IOException {
//要连接的服务器IP地址
String host="127.0.0.1";
//要连接的服务器监听端口
int port=8090;
//与服务器端简历连接
Socket client=new Socket(host,port);
//设置超时间为20秒 ,
client.setSoTimeout(20*1000);
//往服务端写数据
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
//读取控制台
BufferedReader bufReader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("client say:");
writer.write(bufReader.readLine());
writer.write("hello server");
writer.write("eof\n");//设置结束符
writer.flush();
//接收服务端响应,socket从输入流中读取数据是一个阻塞式操作,读取不到数据会一直阻塞
BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
StringBuffer sb=new StringBuffer();
String tmp=null;
int index;
while((tmp=reader.readLine())!=null){
if ((index = tmp.indexOf("eof")) != -1) {//遇到eof时就结束接收
sb.append(tmp.substring(0, index));
break;
}
sb.append(tmp);
}
System.out.println("receive from server:"+sb.toString());
reader.close();
writer.close();
//Test
bufReader.close();
//Test
client.close();
}
}
说明:
1、服务器的ServerSocket的accept方法是用来监听端口,当监听到客户端的socket连接请求是就会创建一个Socket;accept方法是阻塞式的,如果一直没有监听到客户端Socket连接请求,它会一直阻塞下去。
2、Socket的getInputStream()方法也是阻塞式的,客户端的Socket向服务端写入数据后,假如调用getInputStream()方法想要获取服务器端的输出,它会一直阻塞,知道服务器端写入数据或者流关闭。
3、写入”eof“,用来作为结束符,防止流一直阻塞。另外,BufferedReader的readerLine方法也是阻塞式的,知道读取到一行位置,所以写入的时候记得写入换行符。