c - tcp 服务器未绑定(bind)到特定端口

标签 c sockets unix tcp

问题是,无论我设置什么端口,服务器都会连接到不同的端口。 例如,在我的代码中我设置了端口20000(但我也尝试了其他数字),但是当我打印端口号时它完全不同(现在显示8270) 这条线正确吗? indirizzo_serv.sin_port=htons(20000);

另一个问题是服务器不接受多个命令,我的意思是当我发送“时间”并得到答案时,我无法发送任何其他命令。服务器代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<time.h> //per data e ora
#include<locale.h> //per la traduzione di giorno e mese


int main(void)
{
char buf[100]={0},tmp[10]={0};
time_t t; //tempo "grezzo" (rawtime)
struct tm *info; //struttra che contiene le informazioni su data e ora
struct sockaddr_in indirizzo_serv;
int fd1,fd2;
socklen_t len;

setlocale(LC_ALL,"it_IT.utf8"); //per stampare giorno e mese in italiano, ricavato dando da terminale locale -a

indirizzo_serv.sin_family=AF_INET;
indirizzo_serv.sin_port=htons(20000);
indirizzo_serv.sin_addr.s_addr=htonl(INADDR_ANY);
fd1=socket(PF_INET,SOCK_STREAM,0); //socket tcp di rete
bind(fd1,(struct sockaddr*)&indirizzo_serv,sizeof(indirizzo_serv));
listen(fd1,5);

sprintf(tmp,"Numero porta= %d\n",indirizzo_serv.sin_port);
write(STDOUT_FILENO,tmp,strlen(tmp));
bzero(tmp,10);

fd2=accept(fd1,NULL,NULL);

sleep(2);

while(1){
    read(fd2,buf,100);
    if((strcmp(buf,"TIME\n"))==0){
        time(&t);
        info=localtime(&t);
        strftime(buf,100,"Sono le ore %H.%M%n",info);
        write(fd2,buf,strlen(buf));
        bzero(buf,100);
    }
    else if((strcmp(buf,"DATE\n"))==0){
        time(&t);
        info=localtime(&t);
        strftime(buf,100,"Oggi è %A, %e %B %G %n",info);
        write(fd2,buf,strlen(buf));
        bzero(buf,100);
    }
    else if((strcmp(buf,"PORT\n"))==0){
        indirizzo_serv.sin_port=htons(0); //porta casuale
        len=sizeof(indirizzo_serv);
        getsockname(fd1,(struct sockaddr*)&indirizzo_serv,&len);
        sprintf(tmp,"Numero porta= %d\n",indirizzo_serv.sin_port);
        write(STDOUT_FILENO,tmp,strlen(tmp));
        write(fd2,tmp,strlen(tmp)); //invio la porta al client sotto forma di stringa
        bzero(tmp,10);
    }
}

close(fd1);
return 0;
}

客户端代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<ctype.h> //per toupper

int main(void)
{
struct sockaddr_in indirizzo;
int fd,i=0,nport;
char buf[100]={0};

indirizzo.sin_family=AF_INET;
inet_aton("127.0.0.1",&indirizzo.sin_addr);
indirizzo.sin_port=htons(10000);

fd=socket(PF_INET,SOCK_STREAM,0);

connect(fd,(struct sockaddr*)&indirizzo,sizeof(indirizzo));

while(1){
    write(STDOUT_FILENO,"Scrivi il comando da inviare al server tra i seguenti: TIME, DATE, PORT.\n",strlen("Scrivi il comando da inviare al server tra i seguenti: TIME, DATE, PORT.\n"));
    read(STDIN_FILENO,buf,sizeof(buf));
    while(buf[i]){
        buf[i]=toupper(buf[i]);
        i++;
    }
    if((strcmp(buf,"PORT\n"))==0){
            bzero(buf,100);
            read(fd,buf,sizeof(buf));
            nport=atoi(buf);
            indirizzo.sin_port=htons(nport);
            connect(fd,(struct sockaddr*)&indirizzo,sizeof(indirizzo));

    }
    write(fd,buf,strlen(buf)); //incio comando al server
    bzero(buf,100);
    read(fd,buf,100); //leggo il messaggio ricevuto dal server
    write(STDOUT_FILENO,buf,strlen(buf)); //stampo a video il messaggio
    bzero(buf,100);
}

close(fd);
return 0;

}

最佳答案

sprintf(tmp,"Numero porta= %d\n",indirizzo_serv.sin_port);

您创建一个包含端口的网络字节顺序值的字符串。您需要使用 ntohs 获取主机字节顺序:

sprintf(tmp,"Numero porta= %d\n",ntohs(indirizzo_serv.sin_port));

网络字节顺序为big endian而基于现代 x86(或 x86_64)的 PC 是 little endian 。这是您的问题最有可能的原因。

htonsshort 值从主机字节顺序转换为网络字节顺序,而 ntohs 则执行相反的操作。

关于c - tcp 服务器未绑定(bind)到特定端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43558336/

相关文章:

c - 从 .txt 读取的字符串在 C 中无明显原因被重新定义

C 程序在执行 shellcode 时挂起/挂起

sockets - 普通套接字与 SSL 套接字

linux - 如何将所有 Unix 用户执行的所有命令记录在一个文件中?

c++ - C++ 中的 while 循环中始终存在变量

c - 如何对在 Windows 中复制文件的最快方法进行基准测试(内存映射与文件 I/O)

javascript - 套接字IO : Client side 'connect' event not firing when socket is already setup

python - try-except-finally 代码在线程应用程序中无法按预期工作

linux - sed命令只替换一个文件中的值一次

c - 在 Unix/Solaris 中验证用户名