>但應該不是我的電話綁定在這種情況下失敗,
是,如果插座沒有SO_REUSEADDR選項集。
>如果是的話我怎麼可以設置使用本地端口被其他應用程序已經在使用的插座?
您的應用程序和其他應用程序都必須在要綁定到本地端口的套接字上設置SO_REUSEADDR選項。
下面的代碼連接到HTTP服務器,給出命令行參數,從端口1111:
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#define CLIENT_PORT 1111
#define SERVER_PORT 80
int main(int argc, char *argv[]) {
struct sockaddr_in client_name, server_name;
struct hostent *server_info;
if (argc != 2)
return printf("Exactly one argument is required: host to connect\n"), 1;
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0)
return perror("socket"), 1;
/* Without the next 4 lines, bind refuses to use the same port */
int reuseaddr = 1;
if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
sizeof(reuseaddr)) < 0)
return perror("setsockopt"), 1;
client_name.sin_family = AF_INET;
client_name.sin_port = htons(CLIENT_PORT);
client_name.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock_fd, (struct sockaddr *) &client_name,
sizeof(struct sockaddr_in)) < 0)
return perror("bind"), 1;
server_name.sin_family = AF_INET;
server_name.sin_port = htons(SERVER_PORT);
if ((server_info = gethostbyname(argv[1])) == NULL)
return printf("Unknown host: %s\n", argv[1]), 1;
server_name.sin_addr = *(struct in_addr *) server_info->h_addr;
if (connect(sock_fd, (struct sockaddr *) &server_name,
sizeof(server_name)) < 0)
return perror("connect"), 1;
return 0;
}
>如果本地端口我想使用已在使用由其他應用程序會發生什麼?
沒有SO_REUSEADDR(嘗試註釋掉周圍setsockopt
4線),綁定失敗:
$ ./client google.com
$ ./client stackoverflow.com
bind: Address already in use
隨着SO_REUSEADDR,您可以連接到不同的遠程服務器:
$ ./client google.com
$ ./client stackoverflow.com
但是然後連接不會允許你打開兩個相同的套接字s烏爾斯河和目的地:
$ ./client google.com
$ ./client google.com
connect: Cannot assign requested address
對於「將我的'bind'呼叫失敗」的問題,你應該能夠測試它自己,因爲你打算反正編寫這個程序。 – merlin2011
我真的很想知道我可以依賴的行爲和背後的原因,我不是一個專家,不會相信一個測試用例:) – Flash
我也不是網絡編程方面的專家。我提出了這個建議,因爲那是我爲確定答案所做的。 [這個答案](http://stackoverflow.com/a/3329672/391161)有點泛泛,但它可以幫助你朝正確的方向發展。 – merlin2011