مقدمه
آشنایی با مفاهیم برنامه سازی شبکه، یکی از نیازهای مهندسان کامپیوتر می باشد. این افراد در مسیر کار خود با پروژه های شبکه ای روبر خواهند شد که به احتمال زیاد نیاز به برقراری ارتباطات شبکه خواهد داشت. همچنین اگر چنین مساله ای هم اگر پیش نیاید، آشنایی با مفاهیم شبکه، دید بهتری را برای هر مهندس شبکه فراهم می سازد. از اینرو، من قصد دارم در ادامه به شرح مفاهیم و جزئیات برنامه سازی شبکه در لینوکس اشاره کنم. لازم به یاد آوری است که این مفاهیم مستقل از سیستم عامل می باشد و به راحتی می توان از آن در سیستم عاملهای مختلف استفاده کرد.
مدل سرویس دهنده / سرویس گیرنده

این مدل یک معماری نرم افزار توزیع شده است که در آن بارکاری و وظایف بین سرویس دهنده ها (server) و سرویس گیرنده ها (clients) تقسیم می شود. بطور معمول عملیات سرویس دهنده وگیرنده بر روی شبکه کامپیوتری که از سخت افزار مجزا تشکیل شده اند انجام می شود.
یک ماشین سرور، میزبانی است که دارای کارایی بالا (high-performance) بوده و با اجرای یک یا چند برنامه سرویس دهنده، منابع اش را بین سرویس گیرنده ها به اشتراک می گذارد. میزبان سرویس گیرنده منبعی را برای اشتراک ارائه نمی دهد. ولی درخواستش را جهت دریافت سرویس ارسال می کند. بنا براین، سرویس گیرنده، مقداردهی اولیه جهت ایجاد یک نشست ارتباطی را انجام می دهد و سرویس دهنده تنها منتظر (listen) دریافت درخواستها می ماند.
در ارتباطات شبکه ای، هر ماشین با آدرس IP، آدرسدهی می شود و برای آدرسدهی یک پروسس در ماشین از آدرس پورت استفاده می شود.

همانطور که در شکل بالا مشاهده می کنید، سرور FTP از پورت 21 استفاده می کند. با این روش می توان به راحتی چندین سرور را در یک ماشین راه اندازی کرد.
تعریف socket
از دید هسته سیستم عامل (kernel) سوکت یک نقطه انتهایی (endpoint) ارتباط می باشد. ولی از دید برنامه کاربردی، سوکت همانند توصیفگر فایل می باشد که به آن اجازه نوشتن و خواندن به/از شبکه را می دهد.
برنامه های سرویس دهنده و سرویس گیرنده از طریق نوشتن و خواندن در توصیفگر سوکت میتوانند با هم در ارتباط باشند. تفاوت اصلی فایلهای عادی و توصیفگر سوکت در نحوه باز کردن (open) در برنامه کاربردی می باشد.
ترتیب بایتها در شبکه big-endian هست در حالی که میزبان میتواند little-endian نیز باشد. در شکل زیر تفاوت این دو به وضوح نمایش داده شده است.

برای یکسان سازی ترتیب بایتها توابعی طراحی شده است که به قرار زیر می باشند:
- ()htons و ()htonl که ترتیب بایت میزبان را به شبکه تبدیل می کند.
- ()ntohs و ()ntohl که ترتیب بایت را شبکه به میزبان تبدیل می کند.
در ادامه توابع مهم و پارامترهای مورد نیاز آورده شده است. توضیحات مختصر برای هر یک از پارامترها مقابل آن آورده شده است.
•SOCKET: int socket(int domain, int type, int protocol);
–domain := AF_INET (IPv4 protocol)
–type := (SOCK_DGRAM or SOCK_STREAM )
–protocol := 0 (IPPROTO_UDP or IPPROTO_TCP)
–returned: socket descriptor (sockfd), -1 is an error
•
•BIND: int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
–sockfd - socket descriptor (returned from socket())
–my_addr: socket address, struct sockaddr_in is used
–addrlen := sizeof(struct sockaddr)
struct sockaddr_in {
unsigned short sin_family; /* address family (always AF_INET) */
unsigned short sin_port; /* port num in network byte order */
struct in_addr sin_addr; /* IP addr in network byte order */
unsigned char sin_zero[8]; /* pad to sizeof(struct sockaddr) */
};
•LISTEN: int listen(int sockfd, int backlog);
–backlog: how many connections we want to queue
•ACCEPT: int accept(int sockfd, void *addr, int *addrlen);
–addr: here the socket-address of the caller will be written
–returned: a new socket descriptor (for the temporal socket)
•CONNECT: int connect(int sockfd, struct sockaddr *serv_addr, int addrlen); //used by TCP client
–parameters are same as for bind()
•SEND: int send(int sockfd, const void *msg, int len, int flags);
–msg: message you want to send
–len: length of the message
–flags := 0
–returned: the number of bytes actually sent
•RECEIVE: int recv(int sockfd, void *buf, int len, unsigned int flags);
–buf: buffer to receive the message
–len: length of the buffer (“don’t give me more!”)
–flags := 0
–returned: the number of bytes received
•SEND (DGRAM-style): int sendto(int sockfd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen);
–msg: message you want to send
–len: length of the message
–flags := 0
–to: socket address of the remote process
–tolen: = sizeof(struct sockaddr)
–returned: the number of bytes actually sent
•RECEIVE (DGRAM-style): int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
–buf: buffer to receive the message
–len: length of the buffer (“don’t give me more!”)
–from: socket address of the process that sent the data
–fromlen:= sizeof(struct sockaddr)
–flags := 0
–returned: the number of bytes received
–
•CLOSE: close (socketfd);
ارتباطات سرویس دهنده / سرویس گیرنده می تواند اتصال گرا و یا بی اتصال باشد. در شکل زیر نحوه برقراری ارتباط بی اتصال را نشان می دهیم:

و شکل زیر نحوه ارتباط برنامه سرور و مشتری در ارتباط اتصال گرا را نمایش می دهد:

برای بالابردن درک خواننده از مفهوم برنامه سازی شبکه، در لینک زیر مثال ساده echo client-server آورده شده است.
http://www.paulgriffiths.net/program/c/srcs/echoserv.tar.gz