Мультипротокольный клиент-сервер на JAVA
Здравствуйте, я магистрант первого курса Сибирского Государственного Университета Телекоммуникаций и Информатики. В осеннем семестре у нас был предмет «Сетевое программное обеспечение». Как у всех практических предметов и у этого были лабораторные работы. Решение одной как мне показалось очень интересной работы я бы хотел поделиться.
Для начала задание:
1) На языке программирования JAVA написать программу, реализующую работу сервера одновременно по двум протоколам (TCP и UDP). В программе задействовать классы Selector и Thread.
2) Написать две клиентские программы, передающие на сервер файлы по протоколам TCP и UDP соответственно.
Написание программ по отдельности не составило бы большого труда. Нужно было бы просто создать сокет, привязать его к какому-нибудь порту и ждать передачи данных. Но что делать, если нужно передавать по двум протоколам сразу? Для этого мы будем использовать класс Selector.
Суть алгоритма такова: метод select ждет появления события на сокете, после чего в зависимости от ключа события мы решаем по какому протоколу происходит передача данных. Если идет запрос на установление соединения, следовательно это TCP, в противном случае это UDP.
Привожу исходный код сервера:
Исходный код клиентов я писать ввиду их тривиальности.
Для начала задание:
1) На языке программирования JAVA написать программу, реализующую работу сервера одновременно по двум протоколам (TCP и UDP). В программе задействовать классы Selector и Thread.
2) Написать две клиентские программы, передающие на сервер файлы по протоколам TCP и UDP соответственно.
Написание программ по отдельности не составило бы большого труда. Нужно было бы просто создать сокет, привязать его к какому-нибудь порту и ждать передачи данных. Но что делать, если нужно передавать по двум протоколам сразу? Для этого мы будем использовать класс Selector.
Суть алгоритма такова: метод select ждет появления события на сокете, после чего в зависимости от ключа события мы решаем по какому протоколу происходит передача данных. Если идет запрос на установление соединения, следовательно это TCP, в противном случае это UDP.
Привожу исходный код сервера:
package serv;
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.*;
public class serv extends Thread {
Socket s;
int num;
public static void main(String[] args) {
try {
int i = 1;
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking( false );
ServerSocket server = ssc.socket();
InetSocketAddress isa = new InetSocketAddress(1457);
server.bind(isa);
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT );
System.out.println( "Listening on port "+1457 );
DatagramChannel dc = DatagramChannel.open();
dc.configureBlocking( false );
DatagramSocket server2 = dc.socket();
InetSocketAddress isa2 = new InetSocketAddress(1457);
server2.bind(isa2);
dc.register( selector, SelectionKey.OP_READ);
System.out.println( "Listening on port "+1457 );
HashMap map = new HashMap();
byte[] data = new byte[1024];
int f = 0;
System.out.println("server is started");
while(true) {
int num = selector.select();
if (num == 0) {
continue;
}
if (num != 0) {
Set keys = selector.selectedKeys();
Iterator it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
new serv(i, server.accept());
i++;
}
if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
f = 1;
ByteBuffer bb = ByteBuffer.allocate(data.length);
bb.asIntBuffer();
bb.clear();
dc.receive(bb);
data = bb.array();
int len = data.length;
InetAddress addr = InetAddress.getByName(null);
byte[] d = new byte[len-1];
System.arraycopy(data, 1, d, 0, len-1);
switch(data[0]) {
case 'N':
String fname = new String(d);
FileOutputStream file = new FileOutputStream(fname);
System.out.println("File trasfer on UDP");
map.put(addr, file);
break;
case 'F':
file = (FileOutputStream)map.get(addr);
file.write(d);
break;
case 'C':
((FileOutputStream)map.get(addr)).close();
System.out.println("Closing...");
map.remove(addr);
f = 0;
break;
}
}
}
keys.clear();
}
}
}
catch(Exception e) {
System.out.println("Serv init error: "+e);
}
}
public serv(int num, Socket s)
{
this.num = num;
this.s = s;
setDaemon(true);
setPriority(NORM_PRIORITY);
start();
}
public void run()
{
try {
InputStream is = s.getInputStream();
FileOutputStream wfile;
System.out.println("Connection from: " + s.getInetAddress());
int readedBytesCount = 0;
byte[] buf = new byte[2*1024];
System.out.println("File trasfer on TCP");
int len = is.read();
byte[] bname = new byte[len];
is.read(bname, 0, len);
String name = new String(bname);
wfile = new FileOutputStream(name);
while((readedBytesCount = is.read(buf)) != -1) {
wfile.write(buf, 0, readedBytesCount);
}
wfile.close();
System.out.println("Closing...");
s.close();
}
catch(Exception e)
{System.out.println("Server init error(2): "+e);}
}
}
Исходный код клиентов я писать ввиду их тривиальности.
0 комментариев