首先來說一下為什么要設置端口復用,有些時候在調試服務器代碼時勢必會經常啟動或結束服務器進程,這樣就會出現當再次啟動服務器時有可能會出現端口綁定失敗的情況,造成這個情況的原因是由于你上次關閉服務器時有連接尚未斷開等等其他原因,出現綁定失敗也是系統的一個機制,當端口綁定的進程結束時系統會保留一段時間端口的綁定狀態,等過一會再去啟動服務器時就又可以綁定成功了。
也有一種方法,可以實現程序關閉時,立即啟動也可以綁定成功,那就是設置端口復用,下面介紹了如何在Windows和Linux下設置端口復用
Windows/Linux下設置端口復用
Windows和Linux系統下都是使用setsockopt
函數來設置端口復用
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
// sockfd:要設置的文件描述符(包括套接字)
// level:級別,端口復用對應的是SOL_SOCKET
/* optname:選項的名字,下面是復用的選項SO_REUSEADDR:允許將套接字綁定到已在使用中的地址(地址復用)SO_REUSEPORT:允許將套接字綁定到已在使用中的端口(端口復用)**Windows下沒有這個選項,設置SO_REUSEADDR可以達到同樣的效果**
*/
// optval:設置optname選項的值,復用對應的都是int類型
// optlen:optval參數的大小
// 返回值:設置成功返回0,否則返回非0(Linux下返回-1,Windows下返回SOCKET_ERROR)
注意這個函數的調用要在套接字創建之后,綁定之前
示例代碼
// 創建套接字
int fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0)
{std::cout << "網絡初始化失敗\n";return;
}int optval = 1;
// 設置端口復用【Windows下不用設置,因為沒有SO_REUSEPORT】
int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
printf("%s(%d): ret=%d\n", __FILE__, __LINE__, ret);
// 設置地址復用
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
printf("%s(%d): ret=%d\n", __FILE__, __LINE__, ret);sockaddr_in addr{}, clientAddr{};
socklen_t cliAddrLen = sizeof(clientAddr);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; // INADDR_ANY所有的意思
addr.sin_port = htons(9556); // htons主機到網絡
// 綁定端口
if (bind(fd, (sockaddr *)&addr, sizeof(addr)) < 0)
{std::cout << "服務器綁定端口失敗\n";close(fd);return;
}
到這里,windows和Linux下設置套接字端口復用就介紹完了
感謝觀看學習,大佬們多多指點,愿明天的自己會感謝當下的努力!!!!