Передача массива char[] по сети через сокет Беркли и прием через Java Socket
Передача массива char[] по сети через сокет Беркли и прием через Java Socket – это одна из задач, с которой сталкиваются многие разработчики при создании сетевых приложений. Данная статья предназначена для тех, кто хочет узнать подробности передачи и приема данных по сети через сокеты Беркли и Java Socket, а также для тех, кто планирует реализовать подобную логику в своих проектах.
Передача массива char[] по сети через сокеты Беркли
Сокеты Беркли (Berkeley sockets) – это набор функций и структур данных, предоставляемых операционной системой для организации взаимодействия между процессами через сеть. Одним из наиболее распространенных протоколов сетевого взаимодействия, использующих сокеты Беркли, является протокол TCP (Transmission Control Protocol).
Передача данных по сети через TCP выполняется путем создания клиента и сервера, соединенных через сетевой интерфейс. Для создания сокета клиентского приложения необходимо выполнить следующие шаги:
1. Создать сокет, используя функцию socket() – данная функция возвращает дескриптор сокета.
2. Определить адрес и порт сервера, к которому будет выполнено подключение. Для этого необходимо создать структуру данных sockaddr_in, в которую записываются адрес и порт сервера.
3. Подключиться к серверу, используя функцию connect() – данная функция принимает дескриптор сокета клиента, указатель на sockaddr_in и размер структуры.
4. Отправить данные на сервер, используя функцию send() – данная функция принимает дескриптор сокета клиента, указатель на буфер с данными и размер буфера.
Для создания сокета серверного приложения также необходимо выполнить несколько шагов:
1. Создать сокет, используя функцию socket() – данная функция возвращает дескриптор сокета.
2. Определить адрес и порт сервера, на котором будет осуществляться ожидание подключения клиентов. Для этого необходимо создать структуру данных sockaddr_in, в которую записываются адрес и порт сервера.
3. Связать сокет с адресом и портом сервера, используя функцию bind() – данная функция принимает дескриптор сокета сервера, указатель на sockaddr_in и размер структуры.
4. Ожидать подключения клиента, используя функцию listen().
5. Принять подключение от клиента, используя функцию accept() – данная функция принимает дескриптор сокета сервера и указатель на sockaddr_in.
6. Принять данные от клиента, используя функцию recv() – данная функция принимает дескриптор сокета сервера, указатель на буфер и размер буфера.
Теперь, когда мы знакомы с основами создания клиентского и серверного приложений с помощью сокетов Беркли, давайте перейдем к передаче массива char[] по сети с использованием TCP. Для передачи данных по сети необходимо убедиться, что массив char[] имеет правильное кодирование. В основном используется кодирование UTF-8, поэтому рекомендуется приводить данные к этому формату перед отправкой.
Пример передачи массива char[] через сокеты Беркли:
#include
#include
#include
#include
#include
#include
int main(int argc, char const *argv[]) int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = ;
char *hello = «Hello from server»;
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) perror(«socket failed»);
exit(EXIT_FAILURE);
>
// Attaching socket to the port
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt))) perror(«setsockopt»);
exit(EXIT_FAILURE);
>
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding socket to the address and port
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address))
#include
#include
#include
#include
int main(int argc, char const *argv[]) int sock = 0, valread;
struct sockaddr_in serv_addr;
char *hello = «Hello from client»;
char buffer[1024] = ;
// Creating socket file descriptor
if ((sock = socket(AF_INET, SOCK_STREAM, 0))
DevZone Original
Welcome again to my blog! A lot of people have asked me to share a working example of sending and receiving byte array using Java socket programming. So, below is an example for you to get started:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
// A Java program for a Server import java.net.*; import java.util.Arrays; import java.io.*; public class Server //initialize socket and input stream private Socket socket = null; private ServerSocket server = null; private InputStream in = null; private OutputStream out = null; // constructor with port public Server(int port) // starts server and waits for a connection try server = new ServerSocket(port); System.out.println("Server started"); System.out.println("Waiting for a client . "); socket = server.accept(); System.out.println("Client accepted"); // takes input from the client socket in = new DataInputStream(socket.getInputStream()); //writes on client socket out = new DataOutputStream(socket.getOutputStream()); // Receiving data from client ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buffer[] = new byte[1024]; baos.write(buffer, 0 , in.read(buffer)); byte result[] = baos.toByteArray(); String res = Arrays.toString(result); System.out.println("Recieved from client : "+res); //echoing back to client out.write(result); System.out.println("Closing connection"); // close connection socket.close(); in.close(); > catch(IOException i) System.out.println(i); > > public static void main(String args[]) new Server(5000); > >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
// A Java program for a Client import java.net.*; import java.util.Arrays; import java.io.*; public class Client // initialize socket and input output streams private Socket socket = null; private OutputStream out = null; private InputStream in = null; // constructor to put ip address and port public Client(String address, int port) // establish a connection try socket = new Socket(address, port); if (socket.isConnected()) System.out.println("Connected"); > // sends output to the socket out = new DataOutputStream(socket.getOutputStream()); //takes input from socket in = new DataInputStream(socket.getInputStream()); > catch (UnknownHostException u) System.out.println(u); > catch (IOException i) System.out.println(i); > try byte[] arr = (byte)0x00, (byte)0x1F, (byte)0x60, (byte)0x1D, (byte)0xA1, (byte)0x09, (byte)0x06, (byte)0x07, (byte)0x60, (byte) 0x85, (byte)0x74, (byte)0x05, (byte) 0x08, (byte)0x01, (byte)0x01, (byte)0xBE, (byte)0x10, (byte)0x04, (byte)0x0E, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x5F, (byte)0x1F, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x18, (byte)0x1D, (byte)0xFF, (byte)0xFF>; // sending data to server out.write(arr); String req = Arrays.toString(arr); //printing request to console System.out.println("Sent to server : " + req); // Receiving reply from server ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte buffer[] = new byte[1024]; baos.write(buffer, 0 , in.read(buffer)); byte result[] = baos.toByteArray(); String res = Arrays.toString(result); // printing reply to console System.out.println("Recieved from server : " + res); > catch (IOException i) System.out.println(i); > // > // close the connection try // input.close(); in.close(); out.close(); socket.close(); > catch (IOException i) System.out.println(i); > > public static void main(String args[]) new Client("127.0.0.1", 5000); > >
The Client sends a byte array to the Server . Server receives the byte array from the Client and sends the same byte array to the Client .
I have added comments in the code to explain the workflow more clearly.
Байт-массив, передаваемый через сокет
Я пытаюсь отправить простой массив байтов, используя Socket в архитектуре клиент-сервер. Есть проблемы и при отладке с Netbeans, поскольку он дает:
SocketException: сброс соединения
Поэтому я публикую ниже код, и мне бы очень хотелось, чтобы кто-то помог мне.
public class TestClient < /** * @param args the command line arguments */ public static void main(String[] args) < try < Socket s = new Socket("127.0.0.1", 3242); byte[] b; b = "Hello".getBytes(); DataOutputStream os = new DataOutputStream(s.getOutputStream()); os.write(b); >catch (Exception e) < e.printStackTrace(); >>
public class TestServer < public static void main(String[] args) < try < byte[] b = new byte[5]; Socket s = new ServerSocket(3242).accept(); DataInputStream is = new DataInputStream(s.getInputStream()); is.read(b); System.out.println(String.valueOf(b)); >catch (Exception e) < e.printStackTrace(); >>
Я попытался использовать InputStream и OutputStream просто, но поведение такое же.
Результатом выполнения этих кодов является:
System.out.println(String.valueOf(b));
System.out.println(new String(b));
Это преобразует ваш массив байтов в String используя default encoding по default encoding . Он будет работать, если и сервер, и клиент используют одинаковое default encoding иначе вам нужно будет указать кодировку в обеих сторонах следующим образом:
В TestClient «Hello».getBytes(encoding)
В TestServer System.out.println(new String(b, encoding))
То потому что в вашем случае String.valueOf принимает объект как вход (и рассматривает его как объект).
Если вы уверены, что хотите получить String, вы можете вызывать new String(b) или new String(b, «UTF-8») .
Передача байтового массива через сокет
Здравствуйте. Пытаюсь передать серию байтовых массивов (получаемых из скриншотов) с сервера клиенту.
Сервер передает команду 0 — если отправляет массив и команду 1 — если передача массивов закончена. Соответственно клиент получив 0 получает массив, по 1 завершает работу.
Сперва передается размер массива, затем сам массив.
Но все работает лишь тогда, когда между отсылкой массивов на сервере ставлю задержку. Иначе клиент вместо команды 1 или 0 начинает читать байты получаемого массива. Подскажите пожалуйста как правильно организовать передачу массива, причем минимизировав время передачи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
public class Core implements Runnable { private OutputStream outputStream; private InputStream inputStream; BufferedOutputStream bos; BufferedInputStream bis; private byte[] array; private LocalTime time; Core(Socket socket) { try { outputStream = socket.getOutputStream(); inputStream = socket.getInputStream(); bos = new BufferedOutputStream(outputStream); bis = new BufferedInputStream(inputStream); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { for (int i = 0; i 50; i++) { outputStream.write(0); sendScreenAsArray(); } outputStream.write(1); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } private void sendScreenAsArray() { Robot robot; try { //Thread.sleep(100); robot = new Robot(); Rectangle area = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); BufferedImage scr1 = robot.createScreenCapture(area); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(scr1, "jpg", baos); byte[] bytes = baos.toByteArray(); DataOutputStream dataOutputStream = new DataOutputStream(bos); dataOutputStream.writeInt(bytes.length); dataOutputStream.flush(); dataOutputStream.write(bytes); dataOutputStream.flush(); System.out.println("отправлен массив " + bytes.length); } catch (AWTException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
public class Client implements Runnable{ private Socket socket; private InputStream inputStream; private OutputStream outputStream; private BufferedInputStream bis; private BufferedOutputStream bos; Client(){ try { socket = new Socket("192.168.1.110", 8179); inputStream=socket.getInputStream(); outputStream=socket.getOutputStream(); bis=new BufferedInputStream(inputStream); bos=new BufferedOutputStream(outputStream); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { while (true){ try { int command= inputStream.read(); if (command==1){ break; } else if (command==0){ receiveArray(); } else { System.out.println("неожиданная команда"); } } catch (IOException e) { e.printStackTrace(); } } } private void receiveArray(){ DataInputStream dataInputStream=new DataInputStream(bis); byte[] array; try { int arraySize=dataInputStream.readInt(); System.out.println("Получен размер массива "+arraySize); array=new byte[arraySize]; for (int i=0;iarraySize;i++){ array[i]=dataInputStream.readByte(); } System.out.println(LocalTime.now()+" Принят массив "); } catch (IOException e) { e.printStackTrace(); } } }