2010-10-28 32 views
9

Tôi là một lập trình viên giỏi, nhưng tôi không có kinh nghiệm về mạng.Bắt đầu với mạng máy khách-khách hàng

Về cơ bản, tôi muốn tham gia vào mạng khách hàng-máy chủ. Ví dụ, tôi muốn thử một quá trình máy chủ cho phép khách hàng kết nối qua internet và gửi ping cho tất cả các máy khách được kết nối khác. Sau đó, có lẽ tôi sẽ cố gắng phát triển một ứng dụng trò chuyện đơn giản, hoặc một số trò chơi nhiều người chơi đơn giản và tôi sẽ đi từ đó.

Ngôn ngữ tôi biết rất rõ rằng có thể có ích: Java, C++, C.

Làm thế nào để bắt đầu? Tôi muốn tìm hiểu các phương pháp hay nhất ở phía trước, vì vậy các tài nguyên học tập tốt mà bạn có thể đề xuất (ví dụ: sách, tài liệu trực tuyến, v.v.) sẽ tuyệt vời.

Chỉnh sửa: Tôi có nên xem xét một số loại máy ảo để mô phỏng các máy khác nhau tương tác với nhau không?

Chỉnh sửa 2: Tôi đã nạp tiền thưởng 50 lần. Một số câu trả lời tuyệt vời đã được đưa ra cho đến nay - Tôi đang tìm câu trả lời chi tiết hơn mặc dù, vì vậy hy vọng điều này sẽ khuyến khích điều đó. Ví dụ câu trả lời của một người có kinh nghiệm về loại công cụ này so sánh các cách tiếp cận học tập khác nhau sẽ thực sự hữu ích. Cảm ơn! Ngoài ra tôi có thể nhận được một số thông tin phản hồi về toàn bộ điều VM?

+1

Chỉ vì tò mò. Làm thế nào bạn quản lý để "biết rất tốt Java, C và C + +" nhưng không bao giờ tham gia với mạng? – Cratylus

+0

@ user384706: Bằng cách học cú pháp của ngôn ngữ, hầu hết các thư viện của chúng và thu được nhiều kinh nghiệm với chúng. Tôi đã xác định rằng tôi giỏi với các ngôn ngữ đó để giao tiếp rằng tôi không cần các hướng dẫn cho người mới bắt đầu nhằm mục đích dạy lập trình và kết nối mạng với nhau, hoặc hướng đến các lập trình viên mới bắt đầu. Giống như "Bây giờ chúng ta sẽ tìm hiểu vòng lặp while - và sau đó, chúng ta sẽ chuyển sang sử dụng vòng lặp để gửi nhiều phần dữ liệu cùng một lúc" :) – Cam

+1

Máy ảo không thực sự cần thiết trong trải nghiệm của tôi ... bạn có thể mô phỏng nhiều máy chỉ đơn giản bằng cách chạy nhiều tiến trình trong một hệ điều hành duy nhất. –

Trả lời

12

Tôi thích Java. Tôi sẽ giải thích TCP:
Khái niệm cơ bản là bạn phải chạy "Máy chủ" trên máy. Máy chủ đó chấp nhận các máy khách chờ kết nối. Mỗi kết nối đi qua một cổng (bạn biết đấy, tôi hy vọng ...).
Luôn sử dụng các cổng trên 1024 vì các cổng thấp hơn 1025 phần lớn thời gian dành cho các giao thức chuẩn (như HTTP (80), FTP (21), Telnet, ...)

Tuy nhiên, tạo Máy chủ bằng Java được thực hiện theo cách này:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on. 

"Ổ cắm" là từ bạn có thể đang tìm kiếm nếu bạn muốn nghiên cứu.
Và để kết nối khách hàng của bạn đến một máy chủ bạn phải viết này:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port 

Nhưng bây giờ, không có vẫn còn là một kết nối. Máy chủ phải chấp nhận ứng dụng khách chờ đợi (như tôi đã thấy ở trên):

Socket connectionToTheClient = server.accept(); 

Xong! Kết nối của bạn đã được thiết lập! Giao tiếp giống như File-IO. Điều duy nhất bạn phải ghi nhớ là bạn phải quyết định khi nào bạn muốn xóa bộ đệm và thực sự gửi dữ liệu qua socket.
Sử dụng một PrintStream cho văn bản viết là rất tiện dụng:

OutputStream out = yourSocketHere.getOutputStream(); 
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true 
ps.println("Hello, Other side of the connection!"); 
// Now, you don't have to flush it, because of the auto-flush flag we turned on. 

Một BufferedReader cho văn bản đọc là tốt (tốt nhất *) tùy chọn:

InputStream in = yourSocketHere.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
String line = br.readLine(); 
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection. 

Hy vọng rằng bạn có thể bắt đầu với mạng với điều này thông tin!
PS: Tất nhiên, tất cả mã mạng phải được thử bắt đối với IOExceptions.

EDIT: Tôi quên viết lý do tại sao không phải lúc nào cũng là tùy chọn tốt nhất. Một BufferedReader sử dụng một bộ đệm và đọc nhiều như nó có thể vào bộ đệm. Nhưng đôi khi bạn không muốn BufferedReader đánh cắp các byte sau dòng mới và đặt chúng vào bộ đệm của chính nó.
dụ viết tắt:

InputStream in = socket.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
// The other side says hello: 
String text = br.readLine(); 
// For whatever reason, you want to read one single byte from the stream, 
// That single byte, just after the newline: 
byte b = (byte) in.read(); 

Nhưng BufferedReader đã có byte đó, bạn muốn đọc, trong bộ đệm của mình. Vì vậy, gọi in.read() sẽ trả lại byte theo sau trên byte cuối cùng trong bộ đệm của người đọc. Vì vậy, trong tình huống này, giải pháp tốt nhất là sử dụng DataInputStream và quản lý nó theo cách riêng của bạn để biết chuỗi sẽ dài bao nhiêu và chỉ đọc số byte đó và chuyển đổi chúng thành một chuỗi.Hoặc: Bạn sử dụng

DataInputStream.readLine()

Phương pháp này không sử dụng bộ đệm và đọc byte theo byte và kiểm tra dòng mới. Vì vậy, phương pháp này không ăn cắp các byte từ InputStream cơ bản.

6

Hướng dẫn của Beej về Lập trình mạng hoàn toàn vang dội. Sử dụng nó tại trường đại học.

http://beej.us/guide/bgnet/

Nó bao gồm Sockets API và tôi nhớ nó sử dụng C++ cho các ví dụ mã.

Ngoài ra mạng máy tính của Tannenbaum cũng là một bản đọc tuyệt vời.

+0

Trong thực tế, tôi có một số khách hàng cũ và mã máy chủ ... của nó từ ngày Uni của tôi, không phải là mã tốt nhất bao giờ hết, nhưng có thể hữu ích quá! – brumScouse

+0

Tôi đã có một cái nhìn ngắn gọn về cuốn sách (web) này, và trong khi tôi nhận ra nội dung tôi không nghĩ đó là thứ tự tốt nhất cho người mới bắt đầu học về mạng máy chủ khách hàng dựa trên IP. IMNSHO –

+0

Một số khía cạnh khác được hỏi bởi OP được đề cập có thể hữu ích (ví dụ một số chương trình máy khách và máy chủ đơn giản). Tôi đã có cuốn sách được đề cập trong câu trả lời của tôi như một người bạn đồng hành. – brumScouse

1

Đừng bắt đầu với những điều cơ bản nhưng sau đó bạn nên có một cái nhìn vào những gì đang thực sự sử dụng (trong Java):

  1. Để sử dụng lập trình socket Apache Mina.
  2. Ứng dụng máy chủ ứng dụng khách hiện đại sử dụng REST: Jersey, RESTeasy (cả tuân thủ JAX-RS) và Restlet (tiên phong trong trường này).
3

Theo tôi, bạn nên bắt đầu bằng cách học cách sử dụng sockets, giả sử trong C, UNIX (mọi hướng dẫn trực tuyến sẽ phù hợp hoặc sử dụng "người đàn ông"). Và chỉ sau đó bạn có thể google cho thư viện cụ thể ngôn ngữ/hệ điều hành và chọn bất cứ điều gì bạn muốn hoặc bất cứ điều gì sẽ phù hợp hơn với nhu cầu của bạn.

LE: Bạn luôn có thể kiểm tra các ứng dụng của mình trên cùng một máy.

2

Nếu bạn không biết gì về TCP/IP, tôi muốn bắt đầu với cuốn sách tuyệt vời Douglas E. Comer của: TCP/IP Tập 1.

Bạn không cần phải đọc tất cả của nó, có rất nhiều những thứ hữu ích trong đó.

Khi bạn đã đề cập đến điều đó, hãy xem một trong một số triển khai mạng nguồn mở, chẳng hạn như tăng cường asio. IMHO đây là thư viện mạng dễ nhất để thiết lập và chạy. Một khi điều này đã thúc đẩy sự quan tâm của bạn hơn nữa, sau đó bắt đầu điều tra một số chi tiết ổ cắm cấp thấp hơn. Btw, brumScouse đã đề cập đến hướng dẫn của Beej, đây cũng là một nguồn tài nguyên rất tốt.

Và sau đó khi bạn tiếp tục theo dõi và bạn muốn nhiều hơn: google C10K! ;)

+0

Bạn có nói hướng dẫn của Beej nằm trong phạm vi 'chi tiết ổ cắm cấp thấp hơn' không? – Cam

+0

Hãy nói rằng, hướng dẫn đó là về các ổ cắm cơ bản api; thư viện như asio hoặc ACE hoặc bất cứ điều gì đơn giản chỉ cần bọc các chức năng tiếp xúc bởi các ổ cắm api và cung cấp cho bạn abstractions tốt đẹp để làm việc với. Vì vậy, theo nghĩa đó, nó hơi "mức thấp", nhưng đồng thời nó là kiến ​​thức rất hữu ích để bạn biết cách trừu tượng hoạt động. Lý do tôi đề cập đến các abstractions đầu tiên là nó ẩn rất nhiều chi tiết thực hiện mà bạn có thể bị lạc trong ... – Nim

4

Nếu bạn đang sử dụng C++, tôi khuyên bạn nên xem xét sử dụng Boost.Asio đó là thư viện mạng không đồng bộ tuyệt vời sẽ giúp bạn đạt được mục tiêu nhanh hơn nhiều so với sử dụng ổ cắm trực tiếp. Rõ ràng đó là một ý tưởng tuyệt vời để tìm hiểu các công cụ mạng từ mặt đất lên, nhưng tôi nghĩ rằng nó là rất có lợi để làm điều đó với một thư viện tốt (và dễ sử dụng) để trở lại bạn lên để bạn có thể nhận được kết quả quá .

+0

1 cho một giải pháp C++, tôi rất khuyên bạn nên xem Boost.Asio –

6
  1. Hiểu các khái niệm cơ bản về kết nối mạng. Lớp, Địa chỉ IP, Cổng, Gói [Cụ thể UDP/TCP]

  2. Tìm hiểu tóm tắt về lập trình về [1], như Ổ cắm.

  3. Tự mình thực hiện "Máy chủ" và "Máy khách".

  4. Kiểm tra.

  5. Cài đặt Wireshark trên máy tính của bạn và tìm địa chỉ IP, Loại gói, số cổng, v.v. được gửi cho từng loại hoạt động.

  6. Xây dựng trên kiến ​​thức bằng cách sử dụng API mạng của Java/.Net/C++. Nó có lẽ là một ý tưởng rất tồi tệ để xây dựng mọi thứ từ đầu.

Java: http://download.oracle.com/javase/tutorial/networking/index.html

Net: http://msdn.microsoft.com/en-us/library/4as0wz7t.aspx

C++: Unix Mạng Lập trình bởi Richard Stevens

Hy vọng nó giúp.

2

Tôi đến từ một nền tảng lập trình phần lớn mạng Linux. Tôi đã thực hiện một chút lập trình socket Windows, từ những gì tôi đã thấy API socket Windows khá giống với API socket POSIX, và có một số thông tin khá tốt về MSDN để chuyển từ POSIX sang ổ cắm Windows.

Lập trình mạng không thực sự khó khăn về mặt khái niệm, có một vài lĩnh vực mà bạn cần có hiểu biết là có hiệu quả: Trước tiên, bạn cần có hiểu biết cơ bản về kết nối mạng. Bạn sẽ cần ít nhất biết về TCP và IPv4, vì đó có thể là các giao thức mặc định mà bạn sẽ sử dụng. Hiểu biết một chút về DNS và ethernet ở mức khái niệm có thể cũng sẽ hữu ích, nhưng không bắt buộc nghiêm chỉnh lúc đầu. Một khi bạn có một nền tảng cơ bản (đọc một vài bài viết wikipedia hoặc một hướng dẫn cơ bản để kết nối mạng có thể sẽ đủ để bạn bắt đầu), bạn có thể bắt đầu xem xét các API socket POSIX. Đây là khá đơn giản khi bạn có những điều cơ bản về mạng, và có rất nhiều hướng dẫn ở đó (hướng dẫn lập trình mạng của Beej được liệt kê bởi người khác, nó khá tốt, và các trang của người đàn ông thực sự có một số ví dụ khá hữu ích). Chướng ngại lớn nhất mà bạn có thể gặp phải ở đây là biết những gì cần phải theo thứ tự byte mạng so với thứ tự byte của máy chủ, nhưng như một quy tắc của bất kỳ thứ gì mà bạn đang viết vào socket nên được đặt vào thứ tự byte mạng đầu tiên và bất cứ thứ gì bạn đọc từ socket ngay lập tức phải được chuyển đổi sang thứ tự byte của máy chủ.

Trường hợp rất nhiều người vấp ngã là việc học API API POSIX không thực sự đủ để lập trình mạng hiệu quả. Nó sẽ giúp bạn đủ xa để viết một ứng dụng echo đơn giản, nhưng để vượt ra ngoài, có một vài thứ khác bạn cần làm quen. Những cái lớn nhất đang làm việc với các mô tả tập tin không bị chặn, các tín hiệu, làm việc với select/epoll/etc, và nhận được một xử lý trên tiến trình công việc con. Ở mức độ cao, nó khá đơn giản về khái niệm (create-> bind-> listen-> select-> fork-> accept), nhưng nếu bạn không quen với việc làm việc với các bộ mô tả tập tin, chọn, fork, vv thì đó là những thứ bạn sẽ cần phải tăng tốc.

Một trong những chương trình tốt nhất để bắt đầu, theo ý kiến ​​của tôi, là một khách hàng IRC. Nó sẽ cung cấp cho bạn tất cả những điều cơ bản bạn cần (đọc/viết thư đến máy chủ, kết nối đồng thời, xử lý các triển khai máy chủ khác nhau, v.v.), giao thức khá dễ phân tích và có rất nhiều máy chủ để kết nối với.

2

Bạn có thể muốn đọc

Sockets programming in Java: A tutorial

trên JavaWorld. Nó giải thích những điều cơ bản. Đừng cố gắng đi quá xa trong mạng cấp thấp ban đầu. Mã một số máy khách/máy chủ đơn giản để xem nó hoạt động như thế nào.

2

Đây là nội dung chưa được đề cập. Qt

Qt (C++ framework) có lớp "mạng" rất tốt mà tôi đã sử dụng cho kết nối kiểu máy chủ/máy khách TCP và UDP. Có nhiều ví dụ khác nhau mà bao gồm cả:

kết nối Blocking (kết nối đó sẽ làm cho thread hiện hành 'wait' cho một cửa sổ mới)

Non-blocking kết nối (kết nối mà đặt ra call_backs khi dữ liệu có sẵn)

Check it out và bạn sẽ không bao giờ nhìn lại. Họ được tài liệu rất tốt !!!

1

Stevens 'Lập trình mạng UNIX có tất cả thông tin bạn muốn sử dụng API socket BSD (hiện là API ổ cắm tiêu chuẩn) và cách các hệ thống UNIX khác nhau giải thích các chức năng trong các API đó. Nó bao gồm rất nhiều mã trình bày các chủ đề đang thảo luận. Nó cũng rất dày đặc.

Hướng dẫn của Beej là bản tóm tắt nhanh, tốt về cách sử dụng API ổ cắm. Nó có thể là một trong những nơi tốt hơn để bắt đầu và chỉ nhận được hang của cơ học của việc đặt cùng một máy chủ và một khách hàng. Để hiểu tại sao bạn đang thực hiện các cuộc gọi hàm đó với dữ liệu đó theo thứ tự đó và chính xác các cuộc gọi hàm đang làm gì, bạn có thể chuyển sang Stevens.

Nếu bạn muốn nhận các phương pháp hay nhất, hãy xem mã sản xuất: Mongrel 2 xử lý mạng như thế nào? Làm thế nào về lighttpd? Varnish? Tại sao họ xử lý nó theo cách họ làm?

Bạn cũng có thể nhìn vào việc thực hiện của ngăn xếp mạng cho một nền tảng mà bạn đang quan tâm. Lấy mã nguồn hạt nhân, có thể là một cuốn sách thảo luận về thiết kế của hạt nhân, và đào trong.

1

IMHO, lập trình socket trong Java dễ hơn nhiều so với C/C++. Bạn có thể bắt đầu học từ hướng dẫn Java: http://download.oracle.com/javase/tutorial/networking/sockets/

Để lập trình socket C/C++ "cơ bản", bạn có thể học từ "Beej's Guide to Network Programming".Nó là giá trị để tìm hiểu khi tôi đã được ở trường đại học :). Sau đó, bạn có thể tìm hiểu về Windows Socket API cho điểm bắt đầu tiếp theo.

Để mô phỏng môi trường, tất nhiên bạn có thể sử dụng máy ảo :)