关于Socket,本篇博客只为方便自己记忆,具体细节请查看下方地址:
http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html
http://acm.tzc.edu.cn/acmhome/projectList.do?method=projectNewsDetail&nid=2
注意:本篇博客纯粹是为了方便自己记忆查阅用的,如果查看Socket资料的同行看到了,烦请查看上面两个地址,我这块跳过即可。
一、Socket的定义:
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。
但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
二、Socket通讯的过程
Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)
三、TCP协议下使用Socket编程的三种情况
1.客户端给服务端发送数据,服务端接收数据
2.客户端发送内容给服务端,服务端给予反馈
3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接
首先,我们来看一下第一种情况下的简单代码:
public class TCPTest1 {
//注意:
// 异常需要使用try-catch-finally处理,保证流和Socket都可以被关闭
// 需要先开启服务端,再开启客户端
// 客户端
@Test
public void client(){
//2.创建一个Socket,用于数据的发送和接收,//形参指明对方的(服务端)的ip地址和端口号
Socket ss = null;
//3.通过socket获取一个输出流
OutputStream os = null;
try {
//1.创建一个InetAddress类的对象
InetAddress inet = InetAddress.getByName("192.168.56.1");
ss = new Socket(inet, 8989);
os = ss.getOutputStream();
//4.输出流输出数据
os.write("I Love You".getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//5.关闭相应的流和socket
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//服务端
@Test
public void server(){
//1.创建一个ServerSocket的对象]
ServerSocket ss = null;
//2.调用accept(),返回Socket的对象
Socket s = null;
//3.通过Socket获取一个输入流
InputStream is = null;
try {
ss = new ServerSocket(8989);
s = ss.accept();
is = s.getInputStream();
//4.通过输入流,读取数据
byte[] b = new byte[20];
int len;
while ((len = is.read(b))!= -1) {
String str = new String(b, 0, len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (s != null) {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
第二种情况下的简单代码:
public class TCPTest2 {
//正常都应该使用try-catch-finally处理异常
//客户端
@Test
public void client() throws Exception{
//1.
Socket socket = new Socket(InetAddress.getByName("192.168.56.1"), 9898);
//2.
OutputStream os = socket.getOutputStream();
//3.
os.write("客户端请求一个静美的女子做妻子".getBytes());
//关闭输出
socket.shutdownOutput();
//4.
InputStream is = socket.getInputStream();
//5.
byte[] b = new byte[200];
int len;
while((len = is.read(b)) != -1){
String str = new String(b,0,len);
System.out.println(str);
}
//6.
is.close();
os.close();
socket.close();
}
//服务端
@Test
public void server() throws Exception{
//1.
ServerSocket ss = new ServerSocket(9898);
//2.
Socket s = ss.accept();
//3.
InputStream is = s.getInputStream();
//4.
byte[] b = new byte[200];
int len;
while((len = is.read(b)) != -1){
String str = new String(b,0,len);
System.out.println(str);
}
System.out.println(s.getInetAddress().getHostAddress());
//5.
OutputStream os = s.getOutputStream();
os.write("服务端准了".getBytes());
s.shutdownOutput();
//6.
os.close();
is.close();
s.close();
ss.close();
}
}
第三种情况下的简单代码:
public class TCPTest3 {
//客户端
@Test
public void client() throws Exception{
//1.创建一个Socket,用于数据的发送和接收,//形参指明对方的(服务端)的ip地址和端口号
Socket socket = new Socket(InetAddress.getByName("192.168.56.1"), 8888);
//2.用于给客户端发送数据流
OutputStream os = socket.getOutputStream();
//3.用于从本地读取图片
FileInputStream fis = new FileInputStream(new File("zjr1.jpg"));
//4.将图片转化成流的形式,并以流的形式输出
byte[] b = new byte[30];
int len;
while((len = fis.read(b)) != -1){
os.write(b, 0, len);
}
//5.关闭socket
socket.shutdownOutput();
//6.接收从服务端发来的“发送成功”字节流
InputStream is = socket.getInputStream();
byte[] buffer = new byte[20];
int length;
while((length = is.read(buffer)) != -1){
String str = new String(buffer,0,length);
System.out.print(str);
}
//7.由内而外的关闭
is.close();
os.close();
fis.close();
socket.close();
}
//服务端
@Test
public void server() throws Exception{
//1.创建服务端的ServerSocket
ServerSocket ss = new ServerSocket(8888);
//2.调用accept(),返回Socket的对象
Socket s = ss.accept();
//3.创建输入流的对象
InputStream is = s.getInputStream();
//4.将接收到的图片输出保存到本地
FileOutputStream fos = new FileOutputStream(new File("zjr2.jpg"));
//5.以字节的方式输出到本地
byte[] b = new byte[30];
int len;
while((len = is.read(b)) != -1){
fos.write(b, 0, len);
}
//6.输出发送成功
OutputStream os = s.getOutputStream();
os.write("发送成功".getBytes());
//7.关闭
os.close();
fos.close();
is.close();
s.close();
ss.close();
}
}