# فناوری جاوا > برنامه‌نویسی جاوا > مقاله: ارتباط TCP در جاوا

## manvaputra

*ارتباط* *TCP** در جاوا:*
*Socket Programming in Java with TCP.*

در این تاپیک سعی شده به شکلی ساده، برقراری ارتباط کلاینت – سرور با استفاده سوکت پروگرمینگ، با استفاده ازTCP  توضیح داده شود. امید است اساتید  و دوستان  با  ارسال نظرات خود، گامی موثر در زمینه برنامه نویسی تحت شبکه در جاوا، در این سایت بردارند.(با تشکر از دوست همکار عزیزم محسن ثقفی که در تهیه این مقاله همراهم بود)
همانطور که می دانید پروتکل TCP یک پروتکل اتصال گراست. بدین معنی که بر قراری یک ارتباط قبل از هرگونه انتقال اطلاعات الزامیست. همچنین ارتباط ایجاد شده تا پایان انتقال اطلاعات، بین کلاینت و سرور بر قرار می باشد.
از آنجایی که این ارتباط، دارای دو بخش کلاینت و سرور می باشد لذا مراحل آماده سازی جهت این ارتباط، در دو مرحله جدا گانه توضیح داده می شود:


بخش سرور:
پیاده سازی بخش سرور شامل پنج مرحله به شرح زیر می باشد:

*1-**ایجاد سوکت سرور (**ServerSocket object**):*

آرگومان ایجاد سرور سوکت، یک شماره پورت  آزاد می باشد که از محدوده پورت های غیر رزرو (1024 تا 65535) باید انتخاب شود.

ServerSocket mySock = new ServerSocket (1234);

در این مثال یک سرور سوکت با نام mySock بر روی پورت 1234  تعریف شده است.


*2-**قرار دادن سرور در حالت انتظار:*

سرور در انتظار اتصال کلاینت می ماند. این کار با متد accept  از کلاس ServerSocket  انجام می شود. در واقع سرور با این فرمان در انتظار درخواستی از طرف کلاینت می ماند و به پرت تعریف شده در سرور سوکت (در اینجا 1234) گوش می دهد. خروچی این متد، یک شی از جنس سوکت است که از این به بعد، معرف کلاینتی است که پیغامی را به سرور فزستاده است.

Socket mylink = mySock.accept (); 

برنامه سرور، در این خط منتظر یک پیفام از طرف یکی از کلاینتها می ماند. پس از گذر از این خط ، یعنی یک کلاینت درخواستی را ارسال کرده است و ما با mylink به آن دسترسی داریم. *3-**تنظیم جریان های (**Streams**) ورودی و خروجی:*

متد های getInputStream()   و  getOutputStream() از کلاس Socket  ، برای دست یابی به جریانهایی برای انتقال اطلاعات بین کلاینت و سرور بکار می رود.  


DataInputStream input = new DataInputStream( mylink.getInputStream() );

DataOutputStream output=new DataOutputStream(mylink.getOutputStream());


*4-**ارسال و دریافت اطلا عات:* با تعریف input  و output  در مرحله سوم، جریانی مستقیم بین کلاینت و سرور برای ارسال و دریافت اطلاعات فزاهم شده است. در این تاپیک برای ارسال اطلاعات از writeUTF()  و برای دریافت اطلاعات از readUTF()  استفاده شده است. این توابع برای ارسال متن، به خوبی کار می کنند. برای ارسال دیگر انواع داده ای باید از متد های خاص برای ارسال آن نوع اطلاعات استفاده کرد.


Output.writeUTF (“wait for data”);
String request = input.readUTF ();


*5-**بستن ارتباط بعد از خاتمه کار:*

در پایان انتقال اطلاعات، دیگر نیازی به این کانکشن نیست. بهتر است آن را ببندیم.

Mylink.close ();

بخش کلاینت:
پیاده سازی بخش کلاینت  شامل چهار مرحله به شرح زیر می باشد:

*1-**بر پا کردن یک ارتباط با سرور:*

برای این منظور یک سوکت با دو پارامتر زیر تعریف می کنیم:

- آدرس IP   سرور ( از جنس InetAddress  ).
- پورت مورد نظر برای بر قراری ارتباط که سرور به این پورت گوش می دهد . در اینجا فرض می کنیم آدرس IP سرور عدد 192.168.100.67 باشد.


InetAddress ip=InetAddress.getByName("192.168.100.67");
Int port=1234;
Socket mylink=new Socket (ip, port);


*2-**تنظیم جریان های (**Streams**) ورودی و خروجی:*

این بخش دقیقا مانند قسمت سوم سرور می باشد.

*3-** ارسال و دریافت اطلا عات:* این بخش نیز همانند بخش چهار سرور می باشد. *4-** بستن ارتباط بعد از خاتمه کار:*

این بخش نیز عیناً مشابه مرحله 5 سرور می باشد.


mylink.close ();

----------


## manvaputra

اتصال از نوع UDP بزودی

----------


## manvaputra

خوب دوستان عزیز امیدوارم که این مقاله بدردتون خورده باشه در ادامه کد یک برنامه چت ساده رو براتون می ذارم که دقیقا با توجه به آموزش بالا نوشتم البته اینم بگم که منظور از این کد نوشتن چت بصورت حرفه ای نبوده فقط می خواستم آموزش بالا در قالب یک مثال ساده پیاده سازی بشه:

کد سرور چت: 

  import java.net.*;
   import java.io.*;
   import java.util.*;
  public class tcpserver  {
      
    public static void main(String[] args) throws Exception {
              
      
      ServerSocket mysock = new ServerSocket(1254);مرحله اول 
      
      Socket mylink = mysock.accept();مرحله دوم 
      System.out.println("new client conected");
      
 DataInputStream input = new DataInputStream(mylink.getInputStream());مرحل   سوم  
      DataOutputStream output = new DataOutputStream(mylink.getOutputStream());
     
      String request="";
     
     String sendstring;
              Scanner inp = new Scanner(System.in);
      while (  !request.equals("QUIT") )
      {
      
               request = input.readUTF ();مرحله چهارم   
           
              System.out.println(request);
              
              
               sendstring=inp.next();
                          
           output.writeUTF (sendstring);
          
              
      }
         
         mylink.close(); مرحله پنجم   
      
         }
  }
  توی کد بالا مراحل مرتبط با آموزش رو هم نوشتم که اگه گام به گام پیش برید قطعا می تونید این برنامه چت ساده رو بنویسید.

کد کلاینت چت:


   
   import java.net.*;
   import java.io.*;
   import java.util.*;
   public class TCPclient {
      
      public static void main(String[] args) throws Exception {
              
              
    Socket mysock=new Socket(InetAddress.getLocalHost(),1254);
              
    DataInputStream input = new DataInputStream(mysock.getInputStream());
    DataOutputStream output = new DataOutputStream(mysock.getOutputStream());
              
    String request;
      
              
    String sendstring="";
    Scanner inp = new Scanner(System.in);
   
              while (  !sendstring.equals("QUIT"))
              {
              
              sendstring=inp.next();  
               output.writeUTF (sendstring);
               
              request = input.readUTF ();
              System.out.println(request);
                                      
              }
              
              mysock.close(); 
                          
      }
  }
  نکات:
1- طبیعاتا اول برنامه سرور باید اجرا بشه.
2- کلاینت شروع کننده و خاتمه دهنده چت می باشد.
3-مکالمه باید یک در میان باشه یعنی کلاینت یه چیزی بگه بعد سرور جواب بده مجددا نوبت کلاینت میشه.
4- مکالمه با ارسال   QUIT از طرف کلاینت خاتمه پیدا میکنه.

بازم می گم هدف از برنامه بالا نوشتم چت نبوده برای همین اینقدر چت کردن توش شرط و شروط داره  :خجالت:  به همین علت اگه ضعفی هم داره دوستان به بزرگی خودشون ببخشن ما رو :خجالت: 
ولی نکته مهم مربوط میشه به نکته سه یعنی یکی در میان بودن نوع چت به این دلیل که هر یک از دو بخش کلاینت و سرور بعد از ارسال داده منتظر دریافت می مونن یعنی قادر نیستن همزمان هم داده ارسال کنند و هم منتظر دریافت باشن یعنی این برنامه ساده قابلیت همزمانی نداره . دقیقا اینجاست که لزوم THREAD به چشم می خوره ! بزودی آموزش قدم به قدم THREAD نویسی توسط دوست عزیزم محسن آماده میشه و بعد از اون سعی می کنیم به کمک هم کد بالا رو کامل تر کنیم.منتظر اتصال از نوع UDP هم باشید. 
با تشکر از دست اندر کاران این سایت که محیطی مناسب برای تبادل اطلاعات برای  علاقمندان فراهم نموده اند. همچنین با تشکر از استاد عزیزم  Liew Chee Sun که واقعا دری بسوی برنامه نویسی تحت شبکه با جاوا بروی ما گشود.

----------


## rahafrouz

سلام
جگونه می توان آبجکت ویا فایل فرستاد؟

----------


## manvaputra

دوست عزیز سلام فرستادن فایل هم کار پیچیده ای نیست! وقتی شما اتصال رو برقرار کردید به راحتی می تونید اطلاعات رو رد و بدل کنید. توی مثال بالا ما داریم چت می کنیم یعنی رشته می فرستیم خوب کافیه شما به جای فرستادن رشته بتونی بایت بفرستی اون وقت کار ساده میشه شما یه فایل داری که بایت بایت می خونی و میفرستی اون طرف قضیه هم بایت بایت می گیره و ذخیره میکنه اگه می بینید لازمه تا کد هم بنویسم؟

----------


## rahafrouz

دوست عزیز
منظور من آموزش متدهای objectinputstream & objectoutputstream بود.
لطفا متدهای اینها را آموزش دهید  فکر کنم خیلی کاربردی باشه

----------


## manvaputra

چشم من قدم به قدم دارم پیش میرم ممنون از راهنمایی

----------


## victor007

سلام ..
اگر ما دو تا کلاینت در دو سیستم و سرور نیز در یک سیستم دیگر داشته باشیم و بخواهیم سرور ما از طریق یک پورت مثلا 8000 با دو کلاینت ارتباط برقرار کند 
چطوری میشه اینکار رو انجام داد ؟
اگر در این مورد توضیحی بدید ممنون میشم

----------


## samsami

با سلام خدمت دوستان

احتمالا دوست عزیز ما یک برنامه چت تک کلاینتی نوشتند

من دارم روی یک برنامه چت کار می کنم ولی باید با چندین کلاینت مثلا 5 کلاینت کار کنه...

من اینطوری کار می کنم... هر کلاینت با user و pass که برای سرور ارسال می کنه وارد چت روم میشه و این کاربران در آرایه ای ذخیره می شوند 
به این صورت که یک آرایهای از سوکت ها درست کردم و هر زمان که accept می کنم در آرایه ذخیره می کنم .
*
خوب حالا مشکل من اینجا است که چه طوری می تونم در هر زمان از هر کلاینت پیغام دریافت کنم...*

ممنون میشم از پاسختون

----------


## spiderman200700

درود بر شما.
باید به محض وصل شدن هر کلاینت،یه Thread براش ایجاد کنی که کارای مربوط به اون کلاینت رو انجام بده.

----------


## spiderman200700

این برنامه ی چت رو که خودم نوشتم،اینجا میذارم که دوستان ببینن.
البته کدهاشو نذاشتم.چون اگه خدا بخواد و دوستان هم مایل باشند،قصد دارم بعد از اینکه امتحاناتم(که از اول بهمن شروع میشه) تموم شد،آموزش قدم به قدم این برنامه رو توی یه تایپک جدا بذارم.
این برنامه یه برنامه ی چت چند کاربره هست.(تعداد کاربرانی که میتونن به سرور وصل بشن بی نهایته و به قدرت سرور بستگی داره)
البته خیلی کامل نیست و مشکلاتی داره،ولی سعی میکنم تا موقعی که آموزشش رو شروع کنم،کاملترش کنم.

----------


## fshb_ 1370

> خوب دوستان عزیز امیدوارم که این مقاله بدردتون خورده باشه در ادامه کد یک برنامه چت ساده رو براتون می ذارم که دقیقا با توجه به آموزش بالا نوشتم البته اینم بگم که منظور از این کد نوشتن چت بصورت حرفه ای نبوده فقط می خواستم آموزش بالا در قالب یک مثال ساده پیاده سازی بشه:
> 
> کد سرور چت: 
> 
>   import java.net.*;
>    import java.io.*;
>    import java.util.*;
>   public class tcpserver  {
>       
> ...


ممنون از شما به خاطر توضیحاتتون.
میشه در مورد این خط  Scanner inp = new Scanner(System.in);  توضیح بدید که چیکار میکنه؟
شما در پست اولتون گفتین که با Socket mylink = mySock.accept (); سرور منتظر یک پیغام از کلاینت میشه، خوب برای اینکه کلاینت اطلاعاتی بده نباید از output.write استفاده کنه؟ پس چرا شما در کدتون ابتدا از input.read استفاده کردید؟(در سمت سرور)
 می دونم سوالام ی خورده ساده  پیش افتادست اما سوال دیگه، پیش میاد :چشمک:

----------


## spiderman200700

در این جا برنامه سرور جداست برنامه ی کلاین هم جداس.
سرور به محظ accept کردن کلاینت، شروع میکنه به گوش دادن به پیاهایی که از سمت کلاینت میاد(با متد readUTF این کار رو انجام داده).
کلاینت هم به محظ accept شدن درخواست اتصالش از طرف سرور شروع مبکنه به ارسال یه پیام به سرور( با متد writeUTF این کار رو کرده)
کلاس Scanner هم در اینجا برای گرفتن رشته از کاربر استفاده شده.

----------


## fshb_ 1370

مرسی
منظورتون از پیام هایی که از سمت کلاینت میاد چیه؟
خوب مگه پیام هایی که از سمت کلاینت میاد، همون اطلاعاتی نیست که کلاینت میخواد در سمت سرور بنویسه؟
بعد در سمت کلاینت که دیگه متد accept به کاز نبردیم چرا از readUTF استفاد کردین؟

----------


## spiderman200700

همیشه کلاینت درخواست اتصال به سرور رو به سرور میفرسته و سرور این درخواست رو accept میکنه.
بعد از اون هر دو طرف هم میتونن اطلاعاتی رو که از طرف مقابل براشون میاد رو بشنون(بخونن) یا اطلاعاتی رو به طرف مقابل بفرستن(بنویسن) که این کارها در اینجا به ترتیب با متد های  readUTF و writeUTF انجام میشه.

منظورم از پیام همون اطلاعاتیه که دریافت یا ارسال میشه.

----------


## fshb_ 1370

مرسی از توضیحاتتون.

پس چرا ابتدا در سرور میخونه و بعد مینویسه اما در کلاینت برعکسه(یعنی در سرور ابتدا read میاد و بعد write و در کلاینت برعکس)؟ 
چرا باید در سرور یا کلاینت در عمل read و write هم زمان انجام بشه؟ یعنی در while اونها هم read است و هم write ،در صورتی که ممکنه سرور یا کلاینت نخوان هم اطلاعاتی بفرستن و هم بخونن.

ببخشید سوالام انقد میتدیه :خجالت:  فک کنم دیگه اینا سوالای اخرم بود :چشمک:

----------


## spiderman200700

در این برنامه اینطوریه.
در یه برنامه دیه ممکنه سرور اصلا ارسال نداشته باشه.
یا در یه برنامه دیگه ممکنه کلاینت اصلا ارسال نداشته باشه.
یا در یه برنامه ممکنه سرور به چندین کلاینت مختلف به صورت همزمان ارسال داشته باشه.

بسته به نوع برنامه این شرایط متفاوته.شما تصمیم میگری که ارسال و دریافت برنامت چه شکلی باشه.

----------


## gholami.vahid

دوستان سلام
 کسی در مورد ftp در جاوا اطلاعاتی داره  یه توضیحی بده ؟

----------


## spiderman200700

سلام.
در جاوا یه کلاس به نام FtpURLConnection وجود داره که کارش مشابه کار HttpURLConnection هست و هر دو از کلاس انتزاعی URLConnection مشتق شدن.  فقط باید یه آدرس FTP بهش بدی.
در ضمن Request Property ها هم باید مطابق با قوانین FTP باشه.
اینم یه نمونه از نحوه اتصال:
            String urlString="ftp://FTPAddress:21/SubAddress/FileName";
            FtpURLConnection furlc=new FtpURLConnection(new URL(urlString));
            furlc.connect();
            InputStream stream=furlc.getInputStream();

----------


## gholami.vahid

> سلام.
> در جاوا یه کلاس به نام FtpURLConnection وجود داره که کارش مشابه کار HttpURLConnection هست و هر دو از کلاس انتزاعی URLConnection مشتق شدن.  فقط باید یه آدرس FTP بهش بدی.
> در ضمن Request Property ها هم باید مطابق با قوانین FTP باشه.
> اینم یه نمونه از نحوه اتصال:
>             String urlString="ftp://FTPAddress:21/SubAddress/FileName";
>             FtpURLConnection furlc=new FtpURLConnection(new URL(urlString));
>             furlc.connect();
>             InputStream stream=furlc.getInputStream();


ممنونم از پاسخ شما
این دستور برای خواندن رشته  از سرور به کار میره یا نه ؟ آیا برای ارسال و دریافت فایل  به سرور از این طریق  میشه استفاده کرد ؟ممنون میشم اگه کد هاشو  برام بزاری

----------


## spiderman200700

توی این لینک نحوه انجام این کار هست:
http://stackoverflow.com/questions/6...-an-ftp-server

----------


## gholami.vahid

> توی این لینک نحوه انجام این کار هست:
> http://stackoverflow.com/questions/6...-an-ftp-server


ممنونم از لطف عالی

----------


## vejdanamirhoseiin

با سلام 
من این کدهارو  تو سیستم خودم اجرا کردم
اما هیچ جوابی نگرفتم.
قسمت سرورش بدون خطا اجرا میشه اما قسمت کلاینتو که درvmware اجرا میکنم ایناو چاپ میکنه
run:
Exception in thread "main" java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Du  alStackPlainSocketImpl.java:79)
    at java.net.AbstractPlainSocketImpl.doConnect(Abstrac  tPlainSocketImpl.java:339)
    at java.net.AbstractPlainSocketImpl.connectToAddress(  AbstractPlainSocketImpl.java:200)
    at java.net.AbstractPlainSocketImpl.connect(AbstractP  lainSocketImpl.java:182)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.j  ava:172)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.j  ava:392)
    at java.net.Socket.connect(Socket.java:579)
    at java.net.Socket.connect(Socket.java:528)
    at java.net.Socket.<init>(Socket.java:425)
    at java.net.Socket.<init>(Socket.java:241)
    at TCPclient.main(TCPclient.java:9)
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)

----------


## dehghani7212

سلام.
شما بايد اول سرور رو اجرا کنيد و بعدش کلاينت رو. :چشمک:

----------


## shiva.toomuch.todo

سلام
خسته نباشید
تاپیک خیلی کاملی دارید... ممنون جدا
1 سوال داشتم خیـــــــلی جدیه.... کلی سرچ کردم هنوز جوابی پیدا نکردم
چه طور میشه با همین سوکت پروگرمینگ روی مانیتورینگ شبکه کارکرد؟ 
این که چه طور بفهمیم چه پورتی مشغوله رو پیدا کردم اما این که چه طور بفهمم چه برنامه ای روشه رو نه...  :افسرده: 

و این که چه اطلاعاتی داره از اون پورت ها در و بدل می شه؟؟؟؟

1 هفته اس کل سایتای ایرانی و خارجی رو دارم می گردم!!

واقعا ممنون میشم اگه کمک کنید! :قلب: 
واقعا خیـــــــلی جدیه

----------


## ahmad.mo74

یک لایبرری خوب واسه این کار هست libpcap که با استفاده از این میتونی تو جاوا ازش استفاده کنی...حتی برنامه هایی مثل wireshark هم از همین لایبرری استفاده میکنن

----------


## staaaaaar

سلام میشه بگین با اون کد بالا چطور میشه عکس فرستاد و گرفت؟

----------


## MTonyF

با سلام و احترام
خواستم ببینم که این دو تا کدو باید به صورت دو تا کلاس توی اندروید ایجاد کنم
بعدش چ جوری از این دو تا کلاس استفاده کنم؟ینی چ جوری اجراش کنم؟کجای مین اکتیویتی باید چ کدی بذارم؟
ممنونتون میشم راهنمایی بفرمایید

----------


## vahid-p

> با سلام و احترام
> خواستم ببینم که این دو تا کدو باید به صورت دو تا کلاس توی اندروید ایجاد کنم
> بعدش چ جوری از این دو تا کلاس استفاده کنم؟ینی چ جوری اجراش کنم؟کجای مین اکتیویتی باید چ کدی بذارم؟
> ممنونتون میشم راهنمایی بفرمایید


یک نگاه به تاریخ تاپیک بندازید. این تاپیک مربوط به سال 87 هست. نزدیک به 8 یا 9 سال پیش!
به انجمن اندروید مراجعه کنید

----------


## MTonyF

بله تاریخشو میدونم
من الان نیاز به همچین بحثی داشتم و اینو ک پیدا کردم خوبه برام...منتها کمک لازم دارم

----------

