[英]Why specify same port in sin_port in both server and client?
我正在學習C ++中的Socket編程。 我知道套接字必須綁定到服務器地址,而在客戶端,調用connect()
時會有一個內部bind()
。 服務器偵聽struct sockaddr_in
sin_port
中指定的端口。
但是當我在客戶端中為struct sockaddr_in
sin_port
指定相同的端口時,這是否意味着客戶端和服務器都綁定在同一端口上。 我希望這是其中的一部分,我錯了。
以下是代碼:
服務器:
#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
using namespace std;
int main(){
int sockid=socket(AF_INET,SOCK_STREAM,0);
if(sockid<0){
cout<<"failed socket";
}
struct sockaddr_in server, client;
int cz=sizeof(client);
server.sin_family=AF_INET;
server.sin_port=htons(9999);
server.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockid,(struct sockaddr*)&server, sizeof(server))<0){
cout<<"Failed binding";
return 0;
}
cout<<"binded\n";
if(listen(sockid,3)<0){//
cout<<"\nFailed Listening";
return 0;
}
int client_socket=accept(sockid,(struct sockaddr*)&client, (socklen_t*)&cz);
if(client_socket<0){
cout<<"Failed connecting";
return 0;
}
cout<<"Connected....\n";
char buff[1024]={0};
cout<<"enter message: ";
cin>>buff;
if(send(client_socket,buff,strlen(buff),0)<0){
cout<<"\nFailed sending\n";
return 0;
}
cout<<"Message sent";
return 0;
}
客戶
#include<arpa/inet.h>
#include<netdb.h>
#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
using namespace std;
int main(){
int sockid=socket(AF_INET,SOCK_STREAM,0);
if(sockid<0){
cout<<"failed socket";
}
struct sockaddr_in client;
int cz=sizeof(client);
client.sin_family=AF_INET;
client.sin_port=htons(9999);
client.sin_addr.s_addr=INADDR_ANY;
int server_socket=connect(sockid,(struct sockaddr*)&client, sizeof(client));
if(server_socket<0){
cout<<"Failed connecting";
return 0;
}
cout<<"Connected\n";
char buff[250];//
recv(sockid,buff,1024,0);
cout<<"Received msg: "<<buff;
return 0;
}
服務器應bind
到客戶端connect
到的同一端口。 這樣,服務器和客戶端將相互通信。 通常,服務器bind
s bind
到一個眾所周知的端口並listen
s。 客戶端不調用bind
,這導致它綁定到隨機端口。 但它確實調用connect
連接到服務器的知名端口。 服務器在眾所周知的端口上偵聽,發送和接收。 客戶端連接到,發送到已知端口並從其接收。
此外,實際上不要這樣做:
recv(sockid,buff,1024,0);
cout<<"Received msg: "<<buff;
TCP不是基於消息的協議。 當在TCP套接字上調用recv
函數時,它不會收到消息,也不會知道消息是什么。 當你調用一個流的operator<<
並傳遞一個char *
,就像你一樣,它期望char *
指向一個有效的C風格的字符串,這在這段代碼中是不可靠的。 更糟糕的是,您忽略了recv
的返回值,這是了解您收到的字節數的唯一方法。
這里有一個類似的問題:
if(send(client_socket,buff,strlen(buff),0)<0){
您不發送終止零字節,因此接收器無法確定消息的結束位置,而不是您關閉連接的事實。 這僅適用於您要准確發送一條消息然后關閉連接但沒有任何響應可能性的情況。 並且,在這種情況下,接收器需要繼續調用recv
直到它在認為自己已經收到消息之前得到連接已經關閉的指示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.