CÔNG VIỆC CỦA CHÚNG TÔI

+ Đào tạo & hỗ trợ thi & Cấp chứng chỉ Ứng dụng CNTT cơ bản, nâng cao
+ Cung cấp dịch vụ Thiết kế - Lập trình web
+ Các giải pháp triển khai - quản trị hệ thống mạng doanh nghiệp
+ ĐÀO TẠO CHUYÊN NGHIỆP: LẬP TRÌNH (C, .Net, ASP.net, PHP, Thiết kế Đồ họa
Xây dựng ứng dụng client/server DateTime

Xây dựng ứng dụng client/server DateTime

DateTimeServer

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
 * A TCP server that runs on port 9090.  When a client connects, it
 * sends the client the current date and time, then closes the
 * connection with that client.  Arguably just about the simplest
 * server you can write.
 */
public class DateServer {

    /**
     * Runs the server.
     */
    public static void main(String[] args) throws IOException {
        ServerSocket listener = new ServerSocket(9090);
        try {
            while (true) {
                Socket socket = listener.accept();
                try {
                    PrintWriter out =
                        new PrintWriter(socket.getOutputStream(), true);
                    out.println(new Date().toString());
                } finally {
                    socket.close();
                }
            }
        }
        finally {
            listener.close();
        }
    }
}

DateTime Client 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.swing.JOptionPane;
/**
 * Trivial client for the date server.
 */
public class DateClient {

    /**
     * Runs the client as an application.  First it displays a dialog
     * box asking for the IP address or hostname of a host running
     * the date server, then connects to it and displays the date that
     * it serves.
     */
    public static void main(String[] args) throws IOException {
        String serverAddress = JOptionPane.showInputDialog(
            "Enter IP Address of a machine that is\n" +
            "running the date service on port 9090:");
        Socket s = new Socket(serverAddress, 9090);
        BufferedReader input =
            new BufferedReader(new InputStreamReader(s.getInputStream()));
        String answer = input.readLine();
        JOptionPane.showMessageDialog(null, answer);
        System.exit(0);
    }
}

Lập trình mạng TCP Socket (1)

 


Bài 1
Đề bài: Tạo ra hai ứng dụng độc lập (một client và một server). Client chấp nhận một trong các số sau: 1, 2, 3. Số này sẽ được gửi đến server. Server sẽ trả lại tương ứng : “ONE” hoặc “TWO” hoặc “THREE” (tùy theo số nhận được). Dùng giao thức TCP/IPChức năng chương trình:- Client gửi số bất kì đến SERVER
- Nếu là số 1,2,3 thì trả về ONE,TWO,THREE, các trường hợp còn lại trả về UNKNOWN
Cơ chế:- SERVER mở cổng để client truy xuất đến
- Tạo các luồng nhập xuất khi có client truy cập đến (cả client và SERVER), lúc này client và server có thể gửi thông tin qua lại lẫn nhau
- Client truy cập vào, sau đó gửi thông tin đến server
- Server nhận được thông tin, rồi xử lí, sau đó gửi trả lại client
- Client hiển thị thông tin mà server đã trả về


Các lớp và chức năng các lớp:
NumberTCPSimpleServer

- Lớp này có phương thức go(), chức năng của nó:
o Mở cổng của server, tạo kết nối mỗi khi có client kết nối
o Chờ nhận dữ liệu từ Client gửi lêno Xử lí dữ liệu
o Trả về client

- Phương thức main của lớp này tạo ra đối tượng thuộc lớp 
NumberTCPSimpleServer, sau đó gọi phương thức go() của lớp này

Giao tiếp kết thúc nếu nhận được chuỗi "bye"

NumberTCPSimpleClient

- Phương thức khởi tạo của lớp này có đối số là chuỗi về địa chỉ của server
- Phương thức go():

o Tạo kết nối đến địa chỉ và số hiệu cổng của server
o Tạo các luồng nhập xuất liên kết với server
o Đưa dữ liệu cần gửi hoặc nhận vào các luồng này
o Gửi dữ liệu đến server
o Nhận dữ liệu (sau khi server đã xử lí) rồi hiển thị lên màn hìn
Giao tiếp kết thúc nếu nhận được chuỗi "bye"

FULL CODE
NumberTCPSimpleServer .Java 
import java.io.*; 
import java.net.ServerSocket;
import java.net.Socket;
public class NumberTCPSimpleServer {
public static void go() throws IOException {
// Bước 1: Khởi tạo một đối tượng ServerSocket để nghe yêu
// cầu kết nối từ client
// cổng lắng nghe là 9999
ServerSocket socServer = new ServerSocket(9999);
System.out.println("Server in running, on port 9999");
while (true)
{
// Bước 2: Chấp nhận kết nối từ client gửi đến
Socket socClient  = socServer.accept();
System.out.println("Accept client IP:" +  socClient.getInetAddress());
System.out.println("We will working on port:" +  socClient.getPort());
   // Bước 3: lấy các luồng nhập/ xuất để làm việc với client
  // Luồng nhập  từ socket
  InputStream input = socClient.getInputStream();
  InputStreamReader ipR = new InputStreamReader(input);
  BufferedReader buffR= new BufferedReader(ipR);
  
  // Luồng xuất ra socket
  OutputStream ouput = socClient.getOutputStream();
  OutputStreamWriter outW = new OutputStreamWriter(ouput);
  BufferedWriter  buffW = new BufferedWriter(outW);
// Bước 4. Tiến hành giao thức trao đổi dữ liệu
  while (true)
  {
  //(1). Lấy số từ client gửi tới
  String dulieu_Den = buffR.readLine();
  System.out.println(dulieu_Den);
  if (dulieu_Den.compareTo("bye")==0) break;
  //(2). Tính toán kết quả trả về
  String dulieu_Di="UNKNOWN";
  if (dulieu_Den.compareTo("1")==0) dulieu_Di="ONE";
  if (dulieu_Den.compareTo("2")==0) dulieu_Di="TWO";
  if (dulieu_Den.compareTo("3")==0) dulieu_Di="THREE";
  //(3). Gửi về cho client
  buffW.write(dulieu_Di); buffW.newLine(); 
  buffW.flush();
  }
   // Bước 5. Đóng socket
socClient.close();   
}
}
public static void main(String[] args) {
try {
go();
} catch (IOException e) {
e.printStackTrace();
}
}

}

File  NumberTCPSimpleClient .java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class NumberTCPSimpleClient {

public static void go() throws UnknownHostException, IOException
{
//Bước 1: Khởi tạo một đối tượng Socket để kết nối với server
Socket soc = new Socket("localhost",9999);
// Bước 2: 
 // Luồng nhập  từ socket
  InputStream input = soc.getInputStream();
  InputStreamReader ipR = new InputStreamReader(input);
  BufferedReader buffR= new BufferedReader(ipR);
  
  // Luồng xuất ra socket
  OutputStream ouput = soc.getOutputStream();
  OutputStreamWriter outW = new OutputStreamWriter(ouput);
  BufferedWriter  buffW = new BufferedWriter(outW);
    // Bước 3, tiến hành giao thức
      //(0) chuẩn bị
         String dulieu_Di="";
         String dulieu_Den="";
         BufferedReader banPhim = new BufferedReader( 
                               new InputStreamReader(System.in)); 
  
      // Thực hiện
         while (true)
         {
         System.out.println("Mời nhập số (bye để dừng):");
         String dulieu = banPhim.readLine();
         if (dulieu_Den.compareTo("bye")==0) break;
         
         //Gửi đi
         dulieu_Di = dulieu;
         buffW.write(dulieu_Di); buffW.newLine();
         buffW.flush();
         // Lấy về
         dulieu_Den = buffR.readLine();
         System.out.println(dulieu_Den);
         }
// Bước 4. Đóng kết nối
         soc.close();
}
public static void main(String[] args) {
try {
go();
} catch (IOException e) {
e.printStackTrace();
}
}

}

Hướng dẫn tạo LAN trên VMware Workstation - Bài 2

Phương án 2: Chọn kiểu card NAT cho máy ảo:
            Tức là, mạng LAN được hình thành theo cách: Các máy ảo được nối vào switch ảo VMnet8. Cùng nối vào VMnet8 còn có DHCP Server ảo, thiết bị NAT ảo (cả hai do VMware tạo ra và quản lý) nhờ đó mà các máy ảo có thể nhận địa chỉ IP động và kết nối ra mạng ngoài/đi Internet thông qua card mạng của máy thật.           
Trong trường hợp này, các máy ảo phải có địa chỉ mạng (do ta tự chọn) khác với địa chỉ mạng của máy thật. 
Bước 1: Chọn địa chỉ mạng và khai báo một số thông số NAT, DHCP liên quan đến switch ảo VMnet8:

Theo hình trên:
  • Địa chỉ mạng được chọn gắn với switch ảo VMnet8 là 192.168.226.0/24 (thay đổi tại hộp Subnet IP). Địa chỉ này được sử dụng để gắn cho máy ảo sau này;
  • Dịch vụ DHCP cục bộ cũng đã được bật lên;
  • Và một card mạng Ethernet ảo cũng đã được tạo ra (có tên là: VMware Network Adapter VMnet8).
Bạn phải check vào nút: Connet a host virtual adapter to this network thì các máy ảo trong trường hợp này mới có thể thông (ping) với nhau được.
Để thiết lập địa chỉ gateway, và một số thông tin liên quan, ta kích nút NAT Settings…. , hộp thoại sau xuất hiện. Nhập địa chỉ gateway vào hộp Gateway IP. Tại đây bạn cũng có thể thiết lập thông tin cấu hình liên quan đến các dịch vụ DNS và NetBIOS.

Để chỉ ra dãy địa chỉ IP, và một số thông tin liên quan, mà DHCP sẽ dùng để cấp IP cho các máy ảo ta kích nút DHCP Settings…. , hộp thoại sau xuất hiện. Nhập dãy địa chỉ vào các hộp Start IP Address và End IP Address.

Bước 2: Chọn kiểu card mạng NAT cho các máy ảo PC1, PC2 (thực hiện tương tự B1 – Phương án 1):

Kết quả thấy được như hình trên là OK.
            Nếu server DHCP đi cùng VMnet8 đã được cấu hình hợp lệ và đã được bật lên thì ta chỉ cần chỉ định cho các PC1, PC2 nhận địa chỉ IP động là được.
            Nếu sau này trong LAN mà bạn thiết lập có một DHCP server thì bạn có thể tắt DHCP gắn với VMnet8 để các máy PC nhận địa chỉ IP từ DHCP server này.
            Chọn và gán địa chỉ IP, và các thông số liên quan, cho các máy ``ảo PC1, PC2. Địa chỉ được chọn phải thuộc lớp mạng – gắn với VMnet8 – đã khai báo ở Bước 1: 192.168.226.0/24), và phải đảm bảo tính duy nhất giữa các máy tính ảo trong cùng mạng.  
        
Theo hình, máy ảo này có địa chỉ IP là: 192.168.226.11 ; Subnet mask: 255.255.255.0 ; NetID: 192.168.226.0; Gateway: 192.168.226.2 ; Broadcast: 192.168.226.255 và DNS: 8.8.8.8.
Bước 4: Kiểm tra
            Sử dụng lệnh ping để kiểm tra xem các máy ảo có kết nối được với nhau hay không, các máy ảo có nối ra được máy thật hay không (dù khác địa chỉ mạng).
            Nếu máy thật có thể kết nối Internet và duyệt web được thì cũng phải kiểm tra xem các máy ảo có làm được điều này hay không.
            Tất cả đều phải OK thì mới hoàn thành nhiệm vụ các bạn nhé.
Nhận xét:
Theo chúng tôi, bạn nên chọn kiểu card NAT này để tạo LAN từ máy ảo. Nó vừa đơn giản, lại không bị phụ thuộc vào địa chỉ của máy thật. Nhưng cái chính là các máy trong LAN vẫn truy cập Internet và duyệt web bình thường.
Cách này đặc biệt hữu dụng khi máy tính thật là một laptop, thường phải kết nối Internet và duyệt web thông qua hệ thống WIFI ở bất cứ nơi đâu có thể. Tức là cho dù địa chỉ IP tĩnh/động của laptop thay đổi thì vẫn không ảnh hưởng đến LAN máy ảo đã tạo.

Hướng dẫn tạo LAN trên VMware Workstation - Bài 1

Giới thiệu:
Sử dụng máy ảo để triển khai một môi trường đa hệ điều hành, hoặc để thực thi các ứng dụng đơn nền khác nhau, trên cùng một máy tính vật lý là một giải pháp được chọn phổ biến hiện nay, bởi tính đơn giản và hiệu quả của nó.
Với những người đang học tập, nghiên cứu về mạng máy tính hoặc đang triển khai các hệ thống dựa trên mạng máy tính thì giải pháp máy ảo là thực sự cần thiết với họ. Các phần mềm máy ảo giúp họ dễ dàng tạo ra một mạng máy tính “như thật” trên một máy tính vật lý.
Hiện nay có nhiều phần mềm hỗ trợ tạo máy ảo: VMware, Virtual PC,… Nhưng thường được sử dụng nhất vẫn là VMware Workstation.
Bài viết này giúp các bạn tạo ra một mạng LAN gồm các máy ảo Ubuntu Desktop được tạo ra từ VMware Workstation 9.0.2.        
Chuẩn bị:
  • Đảm bảo máy vật lý (máy tính thật) kết nối Internet tốt.
  • Chọn phương án kết nối giữa các máy ảo với nhau và giữa máy ảo với máy thật/Internet (từ đó quyết định chọn loại card ảo phù hợp nhất: Bridge, NAT, Host only hay LAN segment).
  • Tạo hai máy ảo (Ubuntu Desktop – 1Card mạng – Tên: PC1 và PC2) trên WMware. Trong quá trình cài máy ảo ta không cần quan tâm đến việc khai báo địa chỉ IP cho nó (nên tạm chọn chế độ địa chỉ IP động).
  • Chọn địa chỉ mạng cho mạng LAN sẽ tạo. Ví dụ: 192.168.226.0/24.
Thực hiện:
Phương án 1: Chọn kiểu card Bridge cho máy ảo:
Tức là, mạng LAN được hình thành theo cách: Các máy ảo và máy thật cùng nối vào switch ảo VMnet0 (có thể nói theo cách cách: Nối trực tiếp card mạng của máy ảo vào card mạng của máy thật). Trong trường hợp này, các máy ảo phải có cùng lớp địa chỉ mạng với máy thật (xem hinh). 



Nếu máy tính thật có nhiều card mạng thì trước hết ta phải chọn một card mà sẽ được sử dụng để nối mạng với các máy ảo (thông thường nên chọn chế độ tự động)Thực hiện: Kích menu Edit; Kích chọn mục Virtual Network Editor.  Hộp thoại sau xuất hiện:       
 
Kích chọn một card nào đó hoặc chọn Automatic tại mục Bridge to của option Bridged (connect...). Kích Apply và rồi kích OK.
Bước 1: Chọn kiểu card mạng Bridge cho máy ảo PC1:
Kích phải chuột tài biểu tượng card mạng và rồi kích mục Settings… để mở hộp thoại Virtual Machine Settings.
           
Trên hộp thoại Virtual Machine Settings:

Kích chọn nút option Bridged: …. và kích OK.
Kết quả thấy được như hình trên là OK.
Bước 2: Chọn kiểu card mạng Bridge cho máy ảo PC2 (thực hiện tương tự trên máy ảo PC1).
            Nếu máy tính thật có thể nhận địa chỉ IP động từ một DHCP server (với card mạng dùng trong trường hợp Bridge này) nào đó thì ta chỉ cần chỉ định cho các PC1, PC2 nhận địa chỉ IP động từ DHCP này là được.   
            Trước hết kiểm tra địa chỉ IP (động hoặc tĩnh: nên chọn tĩnh), và các thông số liên quan: Subnet Mask, GW, DNS,… , của máy tính thật.
            Chọn và gán địa chỉ IP, và các thông số liên quan, cho các máy ảo PC1, PC2. Địa chỉ được chọn phải cùng địa chỉ mạng với máy thật, và phải đảm bảo tính duy nhất giữa các máy tính trong cùng mạng (subnet).           
Bước 4: Kiểm tra
  • Sử dụng lệnh ping để kiểm tra xem các máy ảo có kết nối được với máy thật hay không, các máy ảo có nối với nhau được hay không.
  • Nếu máy thật có thể kết nối Internet và duyệt web được thì cũng phải kiểm tra xem các máy ảo có làm được điều này hay không.
            Tất cả đều phải OK thì mới hoàn thành nhiệm vụ các bạn nhé.
Nhận xét:
  • Cách này đơn giản, dễ thực hiện, nhưng địa chỉ IP của các máy ảo bị phụ thuộc vào máy thật. Điều này rất bất tiện, có khi là một trở ngại, khi máy ảo được sử dụng làm các server dịch vụ (cần phải hạn chế việc thay đổi địa chỉ IP tĩnh).
  • Cách này chỉ hiệu quả khi máy thật là một laptop, nối mạng qua card WIFI và LAN được tạo chỉ với mục đích chia sẻ tài nguyên và kết nối Internet.
Lập trình mạng - Lấy giờ Internet

Lập trình mạng - Lấy giờ Internet

Bài hướng dẫn lập trình socket client, lấy giờ chuẩn được cấp bới
Host: time.nist.gov
cổng dịch vụ số: 13
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class LayGio {
public static void main(String[] args) {
try {
Socket sc = new Socket("time.nist.gov",13);
//System.out.println("Kết nối TCP thành công");
InputStream input = sc.getInputStream();
InputStreamReader ipR = new InputStreamReader(input);
BufferedReader buff = new BufferedReader(ipR);
// đọc luông và in ra
while (true) {
String line = buff.readLine();
if (line ==null)  break;
else 
System.out.println(line);
}
// đóng socket
sc.close();
} catch (UnknownHostException e) {
System.out.println("Không phân giải được tên");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Server không chấp nhận kết nối"); 
e.printStackTrace();
}
}
}

Thực hành Lập trình mạng - URL - Bài 3 - Download mã HTML

Thực hành Lập trình mạng - URL - Bài 3 - Download mã HTML

Chương trình download mã HTML một trang web và lưu lên máy
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class DownloadHTMLFile {

public static void main(String[] args) {
// TODO Auto-generated method stub
try {
URL u = new URL("http://centrasd.edu.vn");
// Lấy về luồng nhập
InputStream inputWeb = u.openStream();
// Xử lý luồng, và in ra màn hình
InputStreamReader reader = new InputStreamReader(inputWeb);
BufferedReader buff = new BufferedReader(reader);
FileWriter fw = new FileWriter("e:\\abc.html");
BufferedWriter dau_ghi = new BufferedWriter(fw);
while (true) {
String line = buff.readLine();
if (line ==null)  break;
else{
dau_ghi.write(line);
dau_ghi.newLine();
}
}
} catch (MalformedURLException e) {
System.out.println("Định dạng URL bị sai"); 
} catch (IOException e) {
System.out.println("Lỗi khi truy xuất luồng"); 
}
}
}
 
Thực hành Lập trình mạng - URL - Bài 2 - Đọc mã HTML

Thực hành Lập trình mạng - URL - Bài 2 - Đọc mã HTML

Viết chương trình liệt kê toàn bộ nội dung của bất kì trang web nào trên netChức năng chương trình:- Hiển thị thông tin toàn bộ trang web của bất kì trang web nào dưới dạng text đơn thuần
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

public class DocNoiDungTrangWeb {

public static void main(String[] args) {
// TODO Auto-generated method stub
try {
URL u = new URL("http://centrasd.edu.vn");
// Lấy về luồng nhập
InputStream inputWeb = u.openStream();
// Xử lý luồng, và in ra màn hình
InputStreamReader reader = new InputStreamReader(inputWeb);
BufferedReader buff = new BufferedReader(reader);
while (true) {
String line = buff.readLine();
if (line ==null)  break;
else 
System.out.println(line);
}
} catch (MalformedURLException e) {
System.out.println("Định dạng URL bị sai"); 
 } catch (IOException e) {
System.out.println("Lỗi khi truy xuất luồng"); 
}
}
}
 
Thực hành lập trình mạng-URL- bài 1

Thực hành lập trình mạng-URL- bài 1

Đề bài: Viết chương trình xử lí chuỗi nhập, dùng nó để khởi tạo đối tượng URL và trả về thuộc tính của nó 
Chức năng chương trình:- Truy cập vào URL, sau đó in các thông tin của tài nguyên như:o Tên fileo Tên hosto Số hiệu cổngo Kiểu giao thức (https hoặc http hoặc ftp…)

import java.net.*;
import java.util.Scanner;

public class URL_Bai1 {

public static void main(String[] args) {
Scanner banphim = new Scanner(System.in);
System.out.println("Nhập tên file");
String tenfile = banphim.nextLine();
System.out.println("Nhập tên host");
String tenHost= banphim.nextLine();
System.out.println("Số hiệu cổng");
int soCong= Integer.parseInt( banphim.nextLine() );   // ĐỔi chuỗi thành số
System.out.println("Giao thức");
String giaothuc = banphim.nextLine();
try {
URL u = new URL(giaothuc,tenHost, soCong, tenfile);
System.out.println("Giao thức: "+u.getProtocol());
System.out.println("Host: "+u.getHost());
System.out.println("Cổng: "+u.getPort());
System.out.println("File: "+u.getFile());
System.out.println("Full Path: "+u.getPath());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}

Lớp URL trong Java - Đọc code trang web từ một URL và in ra màn hình

Lớp URL trong Java - Đọc code trang web từ một URL và in ra màn hình

Bài đọc code trang web từ một URL và in ra màn hình
import java.net.URL;

 public class DocNoiDungTrangWeb {

  public static void main(String[] args) {
  // TODO Auto-generated method stub
  try {
   URL u = new URL("http://pou.edu.vn/bophants/sp/cong-nghe-thong-tin.340");
   
   // Lấy về luồng nhập
   InputStream inputWeb = u.openStream();
   // Xử lý luồng, và in ra màn hình
   InputStreamReader reader = new InputStreamReader(inputWeb);
   BufferedReader buff = new BufferedReader(reader);
   while (true) {
    String line = buff.readLine();
    if (line ==null)  break;
    else 
     System.out.println(line);
   }
  } catch (MalformedURLException e) {
   System.out.println("Định dạng URL bị sai"); 
  
  } catch (IOException e) {
   System.out.println("Lỗi khi truy xuất luồng"); 
  }
 }
}

Bài giảng Lập trình mạng với Java

Bài giảng Lập trình mạng với Java

Lập trình mạng là một trong những nhiệm vụ căn bản để phát triển các ứng dụng doanh nghiệp. Một chương trình mạng được viết ra để các chương trình trên các máy tính khác nhau có thể truyền tin với nhau một cách hiệu quả và an toàn cho dù chúng được cài đặt trên mạng LAN, WAN hay mạng toàn cầu Internet, đây là điều căn bản đối với sự thành công của nhiều hệ thống.

Java là ngôn ngữ lập trình hướng đối tượng thuần túy với nhiều đặc trưng ưu việt so với các ngôn ngữ lập trình hướng đối tượng khác như tính độc lập với nên, tính bảo mật,…Java là ngôn ngữ ngay từ khi ra đời đã hướng đến lập trình mạng nên việc viết một chương trình lập trình mạng bằng Java dễ dàng hơn nhiều so với các ngôn ngữ khác.

Thư viện phần mềm nguồn mở GitHub trước ngã 3 đường

Thư viện phần mềm nguồn mở GitHub trước ngã 3 đường

(PCWorldVN) Khi gặp áp lực tài chính, một tổ chức nguồn mở luôn cần sáng suốt để chọn cách tồn tại và phát triển. GitHub hiện rơi vào tình cảnh như vậy, điều may mắn là họ có được một bài học nhãn tiền của Sourceforge.
Thư viện Alexandra có lẽ là thư viện cổ lớn nhất thế giới, chứa đựng mọi hiểu biết của con người thời đó. Và đến nay, chắc hẳn nhiều học giả cũng còn nuối tiếc sự "ra đi" của nó. Có vô số bản in và kiến thức lịch sử giá trị đã bị hủy, không gì bù đắp được dù cho thời đại Internet ngày nay có tiến bộ đến đâu chăng nữa. Tuy vậy, những kho chứa kiến thức về một loại nội dung cụ thể nào đó, như thư viện Alexandra trên, vẫn luôn tiềm ẩn những rủi ro.
Ví dụ điển hình: GitHub.

GitHub sẽ đi theo hướng nào: thương mại hoá hay vẫn trung thành với phương châm từ xưa đến nay?
Với giới lập trình viên trên toàn cầu, chẳng ai xa lạ gì với GitHub. Nhưng trong vài năm trở lại đây, GitHub được xem như là thư viện phần mềm nguồn mở lớn nhất trên thế giới. Ngoài việc cung cấp vô số phần mềm và bộ cài đặt, GitHub còn chứa mã nguồn của hàng triệu dự án, nghĩa là bất kỳ ai cũng có thể đọc được mã nguồn của ứng dụng nguồn mở nào đó. Và bởi vì GitHub cũng có chứa các phiên bản cũ của mã nguồn ứng dụng nên nhà lập trình có thể dễ dàng nhận biết được từng bước phát triển của ứng dụng cụ thể và cái cách mà cộng đồng góp sức vào một ứng dụng nguồn mở nào đó.
GitHub cũng là một công cụ giảng dạy lập trình không thể thiếu.
Nhưng với nội dung như vậy, có vẻ như GitHub đang rất giống với thư viện Alexandra. Nhiều đồn đoán cho rằng GitHub sớm kêu gọi đầu tư và sẽ nâng mức giá trị của doanh nghiệp sở hữu GitHub lên đến 2 tỷ USD.
Về mặt tài chính, điều đó đảm bảo cho sự tồn tại của GitHub bền vững hơn trước nay một chút. Nhưng khi nhìn vào bản chất của GitHub, có vẻ có một điều gì đó ngược ngạo. GitHub được xem là một trung tâm chứa phần mềm nguồn mở, là nơi phản ánh sự tự do, tính chia sẻ, lợi ích chung của phần mềm nguồn mở lại được giới đầu tư bỏ tiền vào, là phe xưa nay đối chọi lại với thế giới nguồn mở, thường bỏ vốn cho các doanh nghiệp nguồn đóng. Cho dù nguyên tắc của GitHub đưa ra có là gì đi nữa thì GitHub hiện đang phải chịu áp lực lớn để tồn tại. Khi mà động cơ lợi nhuận và ý chí cộng đồng va phải nhau, nhất là trong thế giới phần mềm thì kết quả luôn luôn không mấy tốt đẹp.

Sourceforge: bài học cần nhớ

Nếu là lập trình viên lâu năm, có lẽ bạn còn nhớ Sourceforge, cũng là một cái hub về phần mềm nguồn mở, giông giống với GitHub hiện nay. Sourceforge từng là nơi để tìm mã nguồn mở trước khi GitHub nổi lên.
Sourceforge đã bị "chìm" chính vì xung đột lợi ích khi dính dáng đến đầu cơ, tiền bạc. Khi DHI Holdings mua lại Sourceforge hồi năm 2012, người dùng đã phải hứng chịu những quảng cáo bên thứ 3 nằm trên nút tải mã nguồn về, khiến họ đôi lúc tải nhầm malware. Sau đó, Sourceforge có đưa ra các công cụ giúp người dùng báo cáo những quảng cáo sai mục đích, nhưng vấn đề vẫn tiếp diễn. Đó là lý do tại sao đội ngũ phát triển GIMP, là bộ công cụ chỉnh sửa hình ảnh miễn phí, cạnh tranh với Adobe Photoshop, đã "nghỉ chơi" với Sourceforge hồi năm 2013 sau nhiều năm để mã nguồn trên ấy.
Thay vì thay đổi cách làm, hồi đầu tháng 6/2015, Sourceforge lại khuấy lên cho đục nước, khi họ công bố đự án GIMP bắt đầu được host ở vài "mirror" trên Sourceforge mà không hề được đội phát triển GIMP cho phép.
Hơn nữa, Sourceforge còn kèm thêm trong bộ cài đặt GIMP phần mềm bên thứ 3, toàn là phần mềm adware và malware. Thế là một số dự án nguồn mở phổ biến khác, trong đó có ứng dụng nghe nhạc, xem phim VLC, ứng dụng viết code Notepad++ và công cụ chạy ứng dụng Windows trên Linux và OS XWINE, rút ra khỏi Sourceforge.
Khó thống kê hết được có bao nhiêu ứng dụng rút ra khỏi Sourceforge vì cách làm của trang web này. Không tính về số lượng người "fork" (chép mã nguồn về máy tính), thì số lượng dự án trên Sourceforge có lẽ cũng gần bằng với trên GitHub.
Nhưng rõ ràng danh tiếng của Sourceforge đã không còn như xưa nữa, cho dù Gaurav Kuchhal, giám đốc quản lý bộ phận của DHI Holdings, người trực tiếp quản lý Sourceforge, cho rằng công ty đã ngưng, không mirror chương trình nào nữa và sẽ chỉ kèm các bộ cài đặt vào mã nguồn nào cho phép họ làm như vậy. Dù thế thì nút quảng cáo giả danh "Download" vẫn còn đó, khiến người dùng thực sự bực bội. Biết rằng Sourceforge cần nguồn thu nhưng chính những cái bẫy không đáng có ấy đã làm lụi bại danh tiếng bấy lâu của họ.

Không quảng cáo (tính đến nay)

GitHub vẫn vững tay cầm chiếc khiên của mình: không hề có quảng cáo. Nếu bạn đẩy mã nguồn lên GitHub thì dịch vụ này hoàn toàn miễn phí. Đó là cách GitHub muốn bạn chia sẻ mã nguồn và phát triển ứng dụng cộng tác. Bạn chỉ phải trả tiền khi muốn không ai xem được mã nguồn ấy (private). GitHub kiếm tiền bằng cách cho các công ty công nghệ những phiên bản private của GitHub, trong đó có cả Facebook, Google và Microsoft.
Dù vậy, rất khó để nói GitHub kiếm được bao nhiêu tiền từ mô hình kinh doanh như vậy, cho dù họ có khách hàng là những công ty tên tuổi. Vấn đề là GitHub chứa hàng triệu dự án nguồn mở miễn phí, không có quảng cáo, không đưa ra giới hạn lưu trữ, băng thông và họ còn có những dịch vụ nằm bên trên những repo (là vùng lưu nguồn mở) ấy. Còn các nhà đầu tư thì luôn muốn có ROI (return of investment) là lẽ đương nhiên, bằng nhiều cách, có thể là mua lại doanh nghiệp sở hữu hoặc niêm yết trên sàn chứng khoán. Một khi điều này xảy ra thì không gì đảm bảo được người sở hữu mới hoặc cổ đông sẽ không nghĩ đến chuyện quảng cáo trên GitHub.
Một số dịch vụ miễn phí khác hiện cũng đang cần gây vốn, như Box và D-ropbox, vì họ cũng chịu áp lực tương tự GitHub. Nhưng GitHub là nơi lưu file tiện hơn nhiều, đồng thời nó còn là "viên đá góc tường" để xây cất phần mềm, là một repo quan trọng của nguồn mở và thành phần cực kỳ quan trọng chứa kiến thức của con người. Nếu chứa quá nhiều kiến thức quan trọng vào một nơi, rồi nơi ấy gặp một rủi ro gì đó, hay thảm họa gì đó, hay rơi vào tay một kẻ tham lam nào đó thì viễn cảnh bạn có thể hình dung là tồi tệ như thế nào rồi.
Điều đáng mừng là GitHub có một cơ chế phòng vệ mà các nhà quản thủ thư viện cổ Alexandra không có. GitHub còn là một cái hub, một trạm trung chuyển, nhưng nó lại không sở hữu Git.

Ông thần Git

Git có thể xem là môt chi (nhánh) quan trọng trên cơ thể GitHub, là một công nghệ nguồn mở, giúp nhà lập trình quản lý những thay đổi trong mã nguồn của mình. Về cơ bản, có một đội ngũ sẽ đặt bản sao mã nguồn gốc (master) vào vị trí trung tâm, và các nhà lập trình khác chỉ việc chép mã nguồn gốc về và tạo/chỉnh sửa/bổ sung thành các phiên bản khác nhau trên máy tính. Nhà lập trình quản lý bản master có thể chọn phiên bản chỉnh sửa nào ưng ý để "merge" để tạo thành bản master khác, làm ra phiên bản master mới nhất (dĩ nhiên các bản master cũ vẫn còn và có thể truy cập ngược lại các bản cũ ấy).
Cách quản lý phiên bản của Git khiến nhà lập trình quản lý dự án của mình rất dễ dàng khi có nhiều người cùng thay đổi mã nguồn gốc. Ngoài ra, nó còn có một hiệu ứng thú vị khác: ai làm việc trên GitHub cũng đều có thể có một bản copy mã nguồn vào máy tính của mình, giống như ai cũng có thể mượn một cuốn sách ở thư viện và giữ luôn, không cần trả lại. Do đó, nếu GitHub hoàn toàn biến mất thì Git có thể gầy dựng lại một GitHub khác, nhưng chuyện này mất rất nhiều thời gian kêu gọi cộng đồng.
GitHub không những là nơi chứa mã nguồn, nó còn là "nhà" của vô số nhận xét, báo cáo lỗi, yêu cầu tính năng mới, đồng thời nó chứa đựng một lịch sử phát triển phần mềm vô cùng phong phú. Chính bản chất phi tập trung của Git đã khiến GitHub tiến xa hơn, mở ra một con đường "cao tốc" cho nhà lập trình di dời dự án của mình lên các host khác, như GitLab (cũng tương tự như GitHub nhưng bạn có thể chạy trên máy chủ của mình).
Tóm lại, nếu GitHub mà chúng ta từng biết trước nay đang phải gánh chịu một áp lực tài chính nào đó và trở nên "đào mỏ" giống Sourceforge thì mã nguồn của thế giới cũng sẽ vẫn tồn tại và phát triển, cũng giống như thư viện mọc lên nhiều nơi cho dù Alexandra có sụp đổ. Nhưng vấn đề là liệu GitHub sẽ tìm cách nào khác hợp tình hợp lý để còn giữ chân giới lập trình, còn là "mảnh đất lành" nữa hay không mà thôi. 
Nguồn tin: www.pcworld.com.vn