简体   繁体   English

为什么在服务器和客户端的sin_port中指定相同的端口?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM