رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران

kambiz behnia

کاربـــر رسمی
  • تعداد ارسال ها

    3
  • تاریخ عضویت

  • آخرین بازدید

اعتبار در سایت

1 خوب

درباره kambiz behnia

توسعه‌ دهنده بَک اِند
توسعه‌ دهنده فرانت اِند
طراحان
  • تاریخ تولد تعیین نشده
  1. kambiz behnia

    هنگام استفاده از دستور select پارامتر اول همواره یک واحد بیشتر از مقدار socket هست. در کدهایی دیده ام که این مقدار را برابر صفر قرار داده اند و همین استفاده ای که شما گفتید را از این دستور کرده اند. البته آن کد برای محیط windows بود (شاید در محیط windows به این پارامتر توجه نکند. حضور ذهن ندارم ولی ظاهرا درویندوز برای همخوانی با توابع c در محیط unix و linux توابعی ارائه داده که از بعضی از پارامترهای آن استفاده نمیشود). در هرحال اگر پارامتر اول را صفر دهیم چه اتفاقی میافتد.
  2. kambiz behnia

    با تشکر از پاسخ بطور خلاصه نتیجه گیری خودم از پاسخ های شما را اینجا می آورم لطفا اطلاح بفرمائید. 1- توابع socket - setsocketopt - bind و listen برای استفاده در Threadها مشکلی ندارند و برای استفاده از آنها نیاز به استفاده متدهایی برای Lockکردن نیست (منظور استفاده از خود توابع بوده و فرض بر این است که پارامترها حتما مختلف خواهند بود) 2- برای استفاده از دستور accept باید از متدهای lock کردن منابع استفاده کرد حتی اگر پارامترها مختلف باشند. 3 - استفاده از توابع select - send , recv همانند قسمت 1 هستند. 4 - اگر یک socket که بطور صحیح ایجاد و قابل استفاده است در اختیار داشته باشیم. میتوانیم در یک Thread فقط کار خواندن و در یک Thread دیگر فقط کار نوشتن روی آنرا انجام دهیم. 5- استفاده از تابع close شرایط واضح خود را دارد و حین و بعد از استفاده از آن پارامتر مشخص شده برای آن نباید در Thread دیگری مورد استفاده باشد. 6 - تابع connect عملکردی مشابه قسمت 5 دارد. سوال 1: اگر مورد 2 صحیح باشد متوجه علت آن نمیشوم چو اگر بقیه برای استفاده در Thread مشکلی نداشته باشند این هم نباید داشته باشد ؟ چون بطور کلی در Thread ها مشکل استفاده از منابه مشترک است آیا توابع ذکرشده منبع حساب میشوند. سوال 2: در بخش اول نپرسیدم نحوه استفاده از errno برای برسی خطا در سوکتها به چه شکل است هر Thread مقدار جداگانه ای برای خود دارد (بعید بنظر میرسد).
  3. kambiz behnia

    باسلام تقریبا مدت زیادی است که درگیر Socket programming و Thread هستم. و هر چند وقت یکبار سوالاتی را در مورد چگونگی استفاده از آنها در فروم های مختلف مطرح و تا حدودی پاسخ خود را یافته ام. با توجه به اینکه گذشت زمان سوالات و شرایط تغییر کرده و لذا خواستم سوالاتی از این دست را یکبار دیگر از ابتدا مطرح و جواب کاملی برای هر کدام داشته باشم. اگر چه امکان دارد جواب هرکدام از این سوالات بطور پراکنده و جداگانه در سایتهای مختلف موجود باشد. علاوه بر آن کمتر جایی یدم که این دو موضوع را با هم بررسی کرده باشند یا فقط به مبحث Thread پرداخته اند ویا فقط درباره Socket توضیح داده اند آن هم فقط در مورد بعضی از توابع مرتبط. حتما دوستان با ترتیب اجرای دستورات و نحوه ایجاد و مفهوم سوکتهای سمت سرور و کلاینت آشنا هستند و هفت نحوه استفاده از آنها نیست بلکه هدف این است اگر من بخواهم از این توابع در Thread های مختلف استفاده کنم آیا امکان پذیر است. آیا پاسخ های داده شده برای محیط Windows, Linux, ... هردو درست است علاوه بر کتابخانه های همراه کمپایلرها کتابخانه های دیگری نظیر Boost - Poco - ACE - Qt - ... هم کتابخانه ای برای کار با شبکه دارند وضعیت توابع مشابه در آنها چگونه است. سوالات رو از سمت سرور شروع میکنم. فرض لازم است سمت سرور 3 سوکت سروری داشته باشیم. SOCKET AcceptSock1; SOCKET AcceptSock2; SOCKET AcceptSock3; حال باید دستورات زیر اجرا شود int InitFunction(SOCKET &AcceptSock) { SOCKET AcceptSock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (AcceptSock == INVALID_SOCKET) { printf("Function socket failed with error : %u\n", WSAGetLastError()); return 0; } int iTimeout = 500; BOOL option = TRUE; int iResult = setsockopt(AcceptSock, SOL_SOCKET, SO_RCVTIMEO, (char *)&iTimeout, sizeof(iTimeout)); if (iResult == SOCKET_ERROR) { printf("Function setsockopt failed with error: %u\n", WSAGetLastError()); return 0; } SOCKADDR_IN client_sin; SOCKADDR_IN local_sin; int iAddrSize = sizeof(client_sin); int iPort = 12345; // select the local interface, and bind to it local_sin.sin_addr.s_addr = htonl(INADDR_ANY); local_sin.sin_family = AF_INET; local_sin.sin_port = htons(iPort); if (bind(AcceptSock, (struct sockaddr *)&local_sin, sizeof(local_sin)) == SOCKET_ERROR) { printf("Function bind failed with error: %u\n", WSAGetLastError()); return 0; } if (listen(AcceptSock, 32) == SOCKET_ERROR) { printf("Function listen failed with error: %u\n", WSAGetLastError()); return 0; } } فانکشن بالا باید برای AcceptSock1 و AcceptSock2 و AcceptSock3 اجرا شود. با اجرای سه کد زیر. InitFunction(AcceptSock1); InitFunction(AcceptSock2); InitFunction(AcceptSock3); سوال آیا من میتوانم هرکدام از سه دستور بالا را در Thread های مختلف اجرا کنم ویا باید حتما در Thread main اجرا شود. برای پذیرش کلاینتهایی که درخواست اتصال دارند از تابع زیر استفاده میکنیم int ProcessFunction(SOCKET &AcceptSock) { fd_set fd; timeval tv; SOCKADDR_IN client_sin; int iAddrSize = sizeof(client_sin); while (true) { tv.tv_sec = 3; tv.tv_usec = 0; FD_ZERO(&fd); FD_SET(AcceptSock, &fd); int iResult = select(0, &fd, NULL, NULL, &tv); if (iResult == SOCKET_ERROR) { printf("Function select failed with error: %u\n", WSAGetLastError()); closesocket(AcceptSock); return 0; } if (iResult == 0) { continue; } SOCKET soc = accept(AcceptSock, (struct sockaddr *) &client_sin, &iAddrSize); if (soc == INVALID_SOCKET) { printf("Function accept failed with error: %u\n", WSAGetLastError()); continue; } //... Do } } که باید برای AcceptSock1 و AcceptSock2 و AcceptSock3 اجرا شود. با اجرای سه کد زیر. ProcessFunction(AcceptSock1); ProcessFunction(AcceptSock2); ProcessFunction(AcceptSock3); سوال سوال آیا من میتوانم هرکدام از سه دستور بالا را در Thread های مختلف اجرا کنم کلا لازم نیست هیچ گونه عملیات لاکی صورت گیرد. آیا من میتواند از AcceptSock1 در دو Thread مختلف استفاده کنم (پاسخ خیر است فقط میخواستم جواب در اینجا باشد). اگر استفاده کنم چه اتفاقی پیش میآید. فانکشن ()WSAGetLastError قطعا Threadsafe نیست ولی آیا توابع دیگری که کد خطا را بروز میکنند Threadsafe نیستند. برای خواندن و نوشتن اطلاعات از Socket پذیرش شده از توابع زیر استفاده می کنیم int SendMessageFunction (SOCKET sock, const char * msg, int len) { fd_set fd; timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&fd); FD_SET(sock, &fd); int iResult = select(0, NULL, &fd, NULL, &tv); if (iResult == SOCKET_ERROR) { printf("Function SendMessage failed with error: %u\n", WSAGetLastError()); return -1; } int rc = send(sock, (char *)msg, len, 0); if (rc != len) { return -1; } return 1; } int ReceiveMessageFunction(SOCKET sock, char * msg, int &len) { fd_set fd; timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&fd); FD_SET(sock, &fd); int i = select(0, &fd, NULL, NULL, &tv); if (i == SOCKET_ERROR) { printf("Function ReceiveMessage failed with error: %u\n", WSAGetLastError()); return -1; } else if (i == 0) { // no data on socket return 0; } // //... //len = ... //... int rc = recv(sock, (char *)msg, len, 0); // ... return 1; } آیا من میتوانم تاوابع بالا را در Threadهای مختلف استفاده کنم و یا خیر. آیا امکان خواندن از یک سوکت توسط دو Thread مختلف امکان پذیر است. نوشتن چطور آیا میتوان یک Thread از Socket بخواند و Thread دیگری در آن بنویسد. با توجه به این موضوع که در یکی از صفحات اینترنتی بیان شده بود که Boost برخلاف کتابخانه های دیگر Threadsafe است (اگرچه امروز هرچه گشتم دوباره آنرا پیدا نکردم) پاسخ با توجه به پلتفورم )Windows, Linux, ..) و کتابخانه مورد استفاده (پیشفرض کمپایلر - ACE - Poco - Boost Qt - ...) در نظر گرفته شود. متشکرم
×