---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
网络编程TCP
Tcp传输
1、tcp分客户端和服务端
2、客户端对应的对象是Socket 服务器端对应的对象是ServerSocket
客户端
通过查询socket对象,发现在该对象建立时,就可以去连接指定主机因为tcp是面向连接的,所以在建立socket服务时就要有服务端存在,并连接成功形成通路后,在该通道进行数据的传输
步骤:
1、创建Socket服务,并指定要连接的主机和端口
2、获取Socket中输出流
3、发送数据
4、关闭客户端
给服务器端发送一段数据
publicclass TcpClient {
publicstaticvoid main(String[] args)throws Exception
{
//创建客户端的Socket服务,指定目的主机和端口
Socket s = new Socket(InetAddress.getByName("192.168.137.165"),10000);
//为了发送数据,应该获取Socket流中的输出流
OutputStream os = s.getOutputStream();
os.write("lsk is on the way!".getBytes());
//关闭客户端服务
s.close();
}
}
服务器端:
1、建立服务器端的Socket服务,ServerSocket() 并监听一个端口
2、获取连接过来的客户端对象
通过ServerSocket的accept方法,没有连接就会等,所以这个方法阻塞式的
3、客户端如果发过来数据,那么服务器端要使用对应的客户端队象,并获取到该客户端
对象的的读取流来读取发过来的数据
4、关闭服务器端
publicclass TcpServer {
publicstaticvoid main(String[] args)throws Exception
{
//建立服务器端Socket服务,并监听一个端口
ServerSocket ss = new ServerSocket(10000);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"connecting!");
//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();
byte[] buf =newbyte[1024];
in.read(buf);
System.out.println(new String(buf,0,buf.length));
s.close();
}
}
下面以同时上传多张图片为例说明TCP传输
服务端
单线程的服务端有个局限性,当A客户端连接上以后,被服务器端获取到,服务端执行具体流程,这是B客户端只能等待。 因为服务器端还没有处理完A客户端的请求,还没没有回来执行循环方法。所以暂时获取不到B客户端的对象,那么为了可以让多个客户端同时并发访问服务器,服务器端最好是将每个客户端封装到一个单独的线程中,这样可以同时处理多个客户端请求。
如何定义线程呢? 只要明确了每个客户端在服务器执行的代码即可,将该代码存入run方法中
class ImgThreadimplements Runnable
{
//定义socket服务
private Sockets;
public ImgThread(Socket s)
{
this.s = s;
}
publicvoid run()
{
try
{
//命名接收到的图片时使用的变量
int count = 1;
//获得发送端的IP地址
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"connecting、、、");
//创建图片文件
File file = new File(ip+"("+(count++)+")"+".jpg");
//如果文件存在,count就加一,保证文件不重名
while(file.exists())
{
file = new File(ip+"("+(count++)+")"+".jpg");
}
//获得Socket的输入流
InputStream is = s.getInputStream();
//创建文件输出流,把上传的文件写入指定文件
FileOutputStream fos =new FileOutputStream("lsk_copy.jpg");
byte[] buf =newbyte[1024];
int len = 0;
while((len = is.read(buf))!=-1)
{
fos.write(buf,0,len);
}
//获得socket的输出流,向客户端写数据
OutputStream os = s.getOutputStream();
os.write("上传成功".getBytes());
//关闭输出流
fos.close();
//关闭服务
s.close();
}
catch(Exception e)
{
thrownew RuntimeException("上传失败");
}
}
}
publicclass TcpImgServer
{
publicstaticvoid main(String[] args)throws Exception
{
//创建tcp服务端并指定端口
ServerSocket ss = new ServerSocket(10001);
//循环接收上传的图片
while(true)
{
Socket s = ss.accept();
new Thread(new ImgThread(s)).start();
}
//ss.close();
}
}
客户端
1、服务端点
2、读取客户端已有的图片数据
3、通过Socket输出流将数据发给服务端
4、读取服务器反馈信息
5、关闭
publicclass TcpImgClient
{
publicstaticvoid main(String[] args)throws Exception
{
//创建发送端服务
Socket s = new Socket("127.0.0.1",10001);
//指定上传的图片文件
FileInputStream fis = new FileInputStream("C:/Users/Administrator/Desktop/刘少康.jpg");
//获得socket的输出流
OutputStream os = s.getOutputStream();
//定义字节数组
byte[] buf =newbyte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{
os.write(buf,0,len);
}
//告诉服务器端数据已写完
s.shutdownOutput();
//获得socket的输入流
InputStream is = s.getInputStream();
//定义字节数组存放接收的数据
byte[] bufin =newbyte[1024];
int len1 = is.read(bufin);
System.out.println(new String(bufin,0,len1));
}
}
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------