[英]Why specify same port in sin_port in both server and client?
I am learning Socket-programming in C++. 我正在学习C ++中的Socket编程。 I understand that the socket must bind to the server address and in the client side, there is an internal
bind()
when connect()
is called. 我知道套接字必须绑定到服务器地址,而在客户端,调用
connect()
时会有一个内部bind()
。 The server listens on the port specified in sin_port
of the struct sockaddr_in
. 服务器侦听
struct sockaddr_in
sin_port
中指定的端口。
But when I specify the same port to sin_port
of the struct sockaddr_in
in client, does that mean that both client and server are bound on the same port. 但是当我在客户端中为
struct sockaddr_in
sin_port
指定相同的端口时,这是否意味着客户端和服务器都绑定在同一端口上。 I hope this is the part, I am going wrong. 我希望这是其中的一部分,我错了。
Here are the codes : 以下是代码:
SERVER : 服务器:
#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;
}
CLIENT 客户
#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;
}
The server should bind
to the same port the client connect
s to. 服务器应
bind
到客户端connect
到的同一端口。 That way, the server and client will be talking to each other. 这样,服务器和客户端将相互通信。 Typically, the server
bind
s to a well-known port and listen
s. 通常,服务器
bind
s bind
到一个众所周知的端口并listen
s。 The client doesn't call bind
, which results in it binding to a random port. 客户端不调用
bind
,这导致它绑定到随机端口。 But it does call connect
to connect to the server's well-known port. 但它确实调用
connect
连接到服务器的知名端口。 The server listens on, sends from, and receives on the well-known port. 服务器在众所周知的端口上侦听,发送和接收。 The client connects to, sends to, and receives from the well-known port.
客户端连接到,发送到已知端口并从其接收。
Also, don't actually ever do this: 此外,实际上不要这样做:
recv(sockid,buff,1024,0);
cout<<"Received msg: "<<buff;
TCP is not a message-based protocol. TCP不是基于消息的协议。 The
recv
function, when called on a TCP socket, does not receive a message nor even know what a message is. 当在TCP套接字上调用
recv
函数时,它不会收到消息,也不会知道消息是什么。 When you call a stream's operator<<
and pass it a char *
, like you are, it expects that char *
to point to a valid C-style string, which is not assured in this code. 当你调用一个流的
operator<<
并传递一个char *
,就像你一样,它期望char *
指向一个有效的C风格的字符串,这在这段代码中是不可靠的。 Worse, you've ignored the return value from recv
which is the only way to know how many bytes you received. 更糟糕的是,您忽略了
recv
的返回值,这是了解您收到的字节数的唯一方法。
There's a similar issue here: 这里有一个类似的问题:
if(send(client_socket,buff,strlen(buff),0)<0){
You don't send the terminating zero byte, so there is no way for the receiver to figure out where the message ends other than by the fact that you then close the connection. 您不发送终止零字节,因此接收器无法确定消息的结束位置,而不是您关闭连接的事实。 This works only in the exact case where you want to send precisely one message and then close the connection without any possibility of a response.
这仅适用于您要准确发送一条消息然后关闭连接但没有任何响应可能性的情况。 And, in this case, the receiver needs to keep calling
recv
until it gets an indication that the connection has been closed before it considers itself to have received a message. 并且,在这种情况下,接收器需要继续调用
recv
直到它在认为自己已经收到消息之前得到连接已经关闭的指示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.