一旦你有一個套接字,你可能要將套接字和機器上的一定的端口關聯 起來。(如果你想用listen()來偵聽一定端口的數據,這是必要一步--MUD 告 訴你說用命令 "telnet x.y.z 6969"。)如果你只想用 connect(),那麼這個步 驟沒有必要。但是無論如何,請繼續讀下去。
這裏是系統調用 bind() 的大概:
#include <sys/types.h>;
#include <sys/socket.h>;
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd 是調用 socket 返回的文件描述符。my_addr 是指向數據結構 struct sockaddr 的指針,它保存你的地址(即端口和 IP 地址) 信息。 addrlen 設置爲 sizeof(struct sockaddr)。
簡單得很不是嗎? 再看看例子:
#include <string.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#define MYPORT 3490
main()
{
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); /*需要錯誤檢查 */
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = inet_addr("132.241.5.10");
bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */
/* don't forget your error checking for bind(): */
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
.
.
.
這裏也有要注意的幾件事情。my_addr.sin_port 是網絡字節順序, my_addr.sin_addr.s_addr 也是的。另外要注意到的事情是因系統的不同, 包含的頭文件也不盡相同,請查閱本地的 man 幫助文件。
在 bind() 主題中最後要說的話是,在處理自己的 IP 地址和/或端口的 時候,有些工作是可以自動處理的。
my_addr.sin_port = 0; /* 隨機選擇一個沒有使用的端口 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 使用自己的IP地址 */
通過將0賦給 my_addr.sin_port,你告訴 bind() 自己選擇合適的端 口。同樣,將 my_addr.sin_addr.s_addr 設置爲 INADDR_ANY,你告訴 它自動填上它所運行的機器的 IP 地址。
如果你一向小心謹慎,那麼你可能注意到我沒有將 INADDR_ANY 轉 換爲網絡字節順序!這是因爲我知道內部的東西:INADDR_ANY 實際上就 是 0!即使你改變字節的順序,0依然是0。但是完美主義者說應該處處一 致,INADDR_ANY或許是12呢?你的代碼就不能工作了,那麼就看下面 的代碼:
my_addr.sin_port = htons(0); /* 隨機選擇一個沒有使用的端口 */
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);/* 使用自己的IP地址 */
你或許不相信,上面的代碼將可以隨便移植。我只是想指出,既然你 所遇到的程序不會都運行使用htonl的INADDR_ANY。
bind() 在錯誤的時候依然是返回-1,並且設置全局錯誤變量errno。
在你調用 bind() 的時候,你要小心的另一件事情是:不要採用小於 1024的端口號。所有小於1024的端口號都被系統保留!你可以選擇從1024 到65535的端口(如果它們沒有被別的程序使用的話)。
你要注意的另外一件小事是:有時候你根本不需要調用它。如果你使 用 connect() 來和遠程機器進行通訊,你不需要關心你的本地端口號(就象 你在使用 telnet 的時候),你只要簡單的調用 connect() 就可以了,它會檢 查套接字是否綁定端口,如果沒有,它會自己綁定一個沒有使用的本地端口。
這裏是系統調用 bind() 的大概:
#include <sys/types.h>;
#include <sys/socket.h>;
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd 是調用 socket 返回的文件描述符。my_addr 是指向數據結構 struct sockaddr 的指針,它保存你的地址(即端口和 IP 地址) 信息。 addrlen 設置爲 sizeof(struct sockaddr)。
簡單得很不是嗎? 再看看例子:
#include <string.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#define MYPORT 3490
main()
{
int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); /*需要錯誤檢查 */
my_addr.sin_family = AF_INET; /* host byte order */
my_addr.sin_port = htons(MYPORT); /* short, network byte order */
my_addr.sin_addr.s_addr = inet_addr("132.241.5.10");
bzero(&(my_addr.sin_zero),; /* zero the rest of the struct */
/* don't forget your error checking for bind(): */
bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
.
.
.
這裏也有要注意的幾件事情。my_addr.sin_port 是網絡字節順序, my_addr.sin_addr.s_addr 也是的。另外要注意到的事情是因系統的不同, 包含的頭文件也不盡相同,請查閱本地的 man 幫助文件。
在 bind() 主題中最後要說的話是,在處理自己的 IP 地址和/或端口的 時候,有些工作是可以自動處理的。
my_addr.sin_port = 0; /* 隨機選擇一個沒有使用的端口 */
my_addr.sin_addr.s_addr = INADDR_ANY; /* 使用自己的IP地址 */
通過將0賦給 my_addr.sin_port,你告訴 bind() 自己選擇合適的端 口。同樣,將 my_addr.sin_addr.s_addr 設置爲 INADDR_ANY,你告訴 它自動填上它所運行的機器的 IP 地址。
如果你一向小心謹慎,那麼你可能注意到我沒有將 INADDR_ANY 轉 換爲網絡字節順序!這是因爲我知道內部的東西:INADDR_ANY 實際上就 是 0!即使你改變字節的順序,0依然是0。但是完美主義者說應該處處一 致,INADDR_ANY或許是12呢?你的代碼就不能工作了,那麼就看下面 的代碼:
my_addr.sin_port = htons(0); /* 隨機選擇一個沒有使用的端口 */
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);/* 使用自己的IP地址 */
你或許不相信,上面的代碼將可以隨便移植。我只是想指出,既然你 所遇到的程序不會都運行使用htonl的INADDR_ANY。
bind() 在錯誤的時候依然是返回-1,並且設置全局錯誤變量errno。
在你調用 bind() 的時候,你要小心的另一件事情是:不要採用小於 1024的端口號。所有小於1024的端口號都被系統保留!你可以選擇從1024 到65535的端口(如果它們沒有被別的程序使用的話)。
你要注意的另外一件小事是:有時候你根本不需要調用它。如果你使 用 connect() 來和遠程機器進行通訊,你不需要關心你的本地端口號(就象 你在使用 telnet 的時候),你只要簡單的調用 connect() 就可以了,它會檢 查套接字是否綁定端口,如果沒有,它會自己綁定一個沒有使用的本地端口。