كيفية إنشاء مأخذ TCP الاتصال باستخدام C إلى منفذ محدد مسبقا

StackOverflow https://stackoverflow.com/questions/204169

  •  03-07-2019
  •  | 
  •  

سؤال

ولدي سؤال بسيط جدا. أريد لاختبار ما إذا كان منفذ معين هو في ظل الاستخدام حاليا أم لا. لهذا، أريد أن ربط مأخذ TCP إلى الميناء، وإذا تم رفض الاتصال يعني المنفذ قيد الاستخدام وإذا لم يكن هذا يعني أن المنفذ مجانا.

ويمكن للشخص من فضلك قل لي كيف يمكنني كتابة التعليمات البرمجية مأخذ TCP في C؟ وأنا على منصة سولاريس.

وأنا أعلم به أساسية جدا. ولكن أنا أقدر مساعدتكم. يرجع الفضل في ذلك مسبقا.

هل كانت مفيدة؟

المحلول

والدعوة إلى ربط وظيفة سيعود -1 إذا كان هناك خطأ. وهذا يشمل الحالة التي يكون فيها عنوان قيد الاستخدام بالفعل.

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 12345

int main()
{
  struct sockaddr_in addr;
  int fd;

  fd = socket(AF_INET, SOCK_STREAM, 0);
  if(fd == -1)
  {
      printf("Error opening socket\n");
      return -1;
  }

  addr.sin_port = htons(PORT);
  addr.sin_addr.s_addr = 0;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_family = AF_INET;

  if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
  {
      printf("Error binding socket\n");
      return -1;
  }

  printf("Successfully bound to port %u\n", PORT);
}

نصائح أخرى

وذلك يعتمد قليلا على بالضبط ما كنت تحاول اختبار.

وعن طريق bind() في الطريقة التي joelc اقترح سوف اقول لكم إذا كان المنفذ مفتوح على أي واجهة على الجهاز الخاص بك. وعلى الرغم من أن تكون شاملة، يجب أن لا إلا أن يكون التحقق من قيمة الإرجاع من bind()، ولكن أيضا فحص errno == EADDRINUSE.

وأي. (تعديل كود joelc ل)


if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1)
{
    if( errno == EADDRINUSE )
    {
        // handle port already open case
    }
    else
    {
        // handle other errors
    }
}

وعن طريق تغيير عنوان المستخدمة في السطر: على سبيل المثال


    sin.sin_addr.s_addr = inet_addr("192.168.1.1");

... يمكنك اختبار ما إذا كان المنفذ هو متاح في واجهة معينة.

وعلى الرغم من أن ندرك أن هذه ليست تجربة مثالية لدولة الميناء. إذا كانت عملية أخرى ميناء مفتوحا وإنهاء قبل إغلاقه برشاقة ميناء (أي قبل استدعاء close() على مأخذ) ثم سوف تحصل عادة في نفس الخطأ EADDRINUSE. (اعتمادا على ما إذا كان قد تم تعيين الخيار SO_REUSEADDR على مأخذ التوصيل)

و(ملاحظة جانبية: ما لم يتم تشغيل التطبيق الاختبار مع امتيازات كافية فلن تكون قادرة على ربط () إلى أي منافذ أدناه 1024)

وكما اقترح مجهول، يمكنك أيضا إلقاء نظرة على netstat. هذا وسوف تعطيك كل نفس المعلومات التي يمكنك الحصول عليها من خلال الدعوة المتكررة bind() بسرعة أكبر بكثير، ودون أي آثار جانبية (مثل ذلك لا يجب أن تربط في الواقع إلى الموانئ، والتي من شأنها أن تجعلها غير صالحة للاستعمال على أي عمليات أخرى ). فقط يدعو netstat -a --numeric-ports -t ويجب تحليل الناتج تعطيك كل ما كنت بعد.

وتعليق على moogs اقتراح على الرغم - يدعو تلنت على كل منفذ وسوف اقول لك فقط إذا كان مأخذ يتم الاستماع على هذا المنفذ - ليس ما إذا كان مفتوحا فعلا

.

هل كنت ترغب فقط لاختبار إذا كان منفذ معين قيد الاستخدام حاليا؟ (ولا تحتاج حقا لجعل البرنامج). إذا كان الأمر كذلك، يمكنك استخدام telnet:

<اقتباس فقرة>   

والتلنت الميناء المضيف

إذا فشل الاتصال، فإنه لا تكون قيد الاستعمال. إذا كان يتصل وينتظر إدخال من قبلك، انها قيد الاستخدام:)

وأنت قد ترغب في النظر في شفرة المصدر من NETSTAT. أعتقد أن هناك NETSTAT في سولاريس كذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top