Мультипротокольный клиент-сервер на JAVA

Здравствуйте, я магистрант первого курса Сибирского Государственного Университета Телекоммуникаций и Информатики. В осеннем семестре у нас был предмет «Сетевое программное обеспечение». Как у всех практических предметов и у этого были лабораторные работы. Решение одной как мне показалось очень интересной работы я бы хотел поделиться.

Для начала задание:

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 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.