PDA

View Full Version : در مورد structureها و توابع winsock سوال دارم



g2eenday
جمعه 01 آذر 1387, 01:21 صبح
سلام به همه اگر امکانش هست در مورد توابع زیر یه توضیحی بدید:
()WSAStartup
()MAKEWORD
این درسته که پارامترهای MAKEWORD رو برعکس می گذارند؟(یعنی اگر ورژن x.y باشه تابع رو به صورت (MAKEWORD(y,x می نویسند؟

اگه می شه در مورد این Structure توضیحی بدهید ممنون می شم:
SOCKET
sockaddr_in
sockaddr
تفاوت sockaddr_in با sockaddr در چیست؟
چرا تابع زیر پارامترهایش به این صورت هست؟
((bind(m_socket, (SOCKADDR*)&service, sizeof(service

حالا سورس client و server اونو اینجا می زارم کسی اگه سوالای بالا رو جواب بده ممنون می شم :لبخندساده:



#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib");
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
printf("Server: The Winsock dll not found!\n");
return 0;
}
else
{
printf("Server: The Winsock dll found!\n");
printf("Server: The status: %s.\n", wsaData.szSystemStatus);
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )
{
printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
WSACleanup();
return 0;
}
else
{
printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
printf("Server: The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));
}
SOCKET m_socket;
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
printf("Server: Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else
{
printf("Server: socket() is OK!\n");
}

sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(55555);
if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
{
printf("Server: bind() failed: %ld.\n", WSAGetLastError());
closesocket(m_socket);
return 0;
}
else
{
printf("Server: bind() is OK!\n");
}
if (listen(m_socket, 10) == SOCKET_ERROR)
printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());
else
{
printf("Server: listen() is OK, I'm waiting for connections...\n");
}
SOCKET AcceptSocket;
printf("Server: Waiting for a client to connect...\n" );
printf("***Hint: Server is ready...run your client program...***\n");
while (1)
{
AcceptSocket = SOCKET_ERROR;
while (AcceptSocket == SOCKET_ERROR)
{
AcceptSocket = accept(m_socket, NULL, NULL);
}
printf("Server: Client Connected!\n");
m_socket = AcceptSocket;
break;
}
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[200] = "This string is a test data from server";
char recvbuf[200] = "";
printf("Server: Sending some test data to client...\n");
bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);
if (bytesSent == SOCKET_ERROR)
printf("Server: send() error %ld.\n", WSAGetLastError());
else
{
printf("Server: send() is OK.\n");
printf("Server: Bytes Sent: %ld.\n", bytesSent);
}
bytesRecv = recv(m_socket, recvbuf, 200, 0);
if (bytesRecv == SOCKET_ERROR)
printf("Server: recv() error %ld.\n", WSAGetLastError());
else
{
printf("Server: recv() is OK.\n");
printf("Server: Received data is: \"%s\"\n", recvbuf);
printf("Server: Bytes received: %ld.\n", bytesRecv);
}
WSACleanup();
return 0;
}






#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib,"ws2_32.lib");
int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
printf("Client: Error at WSAStartup().\n");
else
printf("Client: WSAStartup() is OK.\n");
SOCKET m_socket;
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());
WSACleanup();
return 0;
}
else
printf("Client: socket() is OK.\n");
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(55555);
if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
printf("Client: connect() - Failed to connect.\n");
WSACleanup();
return 0;
}
else
{
printf("Client: connect() is OK.\n");
printf("Client: Can start sending and receiving data...\n");
}
int bytesSent;
int bytesRecv = SOCKET_ERROR;
char sendbuf[200] = "This is a test string from client";
char recvbuf[200] = "";
while(bytesRecv == SOCKET_ERROR)
{
bytesRecv = recv(m_socket, recvbuf, 200, 0);
if (bytesRecv == 0 || bytesRecv == WSAECONNRESET)
{
printf("Client: Connection Closed.\n");
break;
}
if (bytesRecv < 0)
return 0;
else
{
printf("Client: recv() is OK.\n");
printf("Client: Received data is: \"%s\"\n", recvbuf);
printf("Client: Bytes received is: %ld.\n", bytesRecv);
}
}
bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);
if(bytesSent == SOCKET_ERROR)
printf("Client: send() error %ld.\n", WSAGetLastError());
else
{
printf("Client: send() is OK - Bytes sent: %ld\n", bytesSent);
printf("Client: The test string sent: \"%s\"\n", sendbuf);
}

WSACleanup();
return 0;
}

Nima_NF
جمعه 01 آذر 1387, 22:36 عصر
WSAStartup باید به عنوان اولین تابع برای کار با socket فراخوانی شود تا نسخه dll مورد نظر ما تعیین شود و مشخصات نهایی آن نیز با توجه به شرایط سیستم و dll های موجود آن برگردانده شود.

MAKEWORD هم یک ماکرو هست نه تابع، پارامتر اول low-order byte که برای major version است و پارامتر دوم آن high-order byte که برای minor version است.
پس بله، جابجا باید بنویسید.

برای مقدار خروجی socket از SOCKET استفاده می شود که با توجه به مقادیر از پیش تعریف شده یکی از پیام های خطا را بر می گرداند، لیست تمامی خطاها به همراه شماره آن ها در document های تابع WSAGetLastError در قسمت "Windows Sockets Error Codes" قرار دارد، از MSDN استفاده کنید.

برای struct ها در ++VC در صورتی که هدر فایل مورد نیاز را include کرده اید، در جایی از کدها آن ها را بنویسید و سپس بر روی آن راست کلیک کنید و گزینه Go to definition را برنید تا به بخش تعریف آن بروید، پس برای نسخه های sockaddr این کار را انجام دهید تا متغیر های تعریف داخل آن ها را مشاهده کنید.

همیشه برای تعریف پارامترهای توابع از MSDN یا سایر document ها استفاده کنید.
پارامتر اول bind همان مقدار برگشتی تابع socket هست
پارمتر دوم آن اشاره گری به sockaddr است و چون معمولا یک نسخه از sockaddr می سازیم نه اشاره گر، پس تبدیل صریح به اشاره گر می کنیم و با & آدرس آن را ارسال می کنیم.
پارامتر سوم هم که اندازه همان sockaddr در پارامتر دوم هست، که با sizeof بدست می آوریم.