c - 在c中使用UDP和TCP套接字编程建立连接

标签 c sockets

我正在尝试用相同的代码建立 UDP 和 TCP 连接。我有 3 个程序,其源代码位于 server.ctransfer.cclient.c 中。我希望第一个 server 运行并等待数据;然后传输,然后客户端

我想要的结果是,如果我在 client 中输入消息,它会使用 TCP 发送到 transfer,然后 transfer 将此消息转发到使用 TCP 的服务器。当服务器收到消息时,它会检查消息是字母还是数字。如果是 alpha,服务器 使用 UDP 向客户端发送“这不是数字”消息。如果是数字,它只是使用 UDP 将相同的消息转发到客户端

我能够使用 TCP 向服务器发送消息,但无法使用 UDP 向客户端发送特定消息。知道出了什么问题吗?

这是我的代码。这是我的server.c:

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

#define PORTNUM 2400
#define MAXRCVLEN 500
#define SERVER "127.0.0.1" // local server
#define BUFLEN 512  //Max length of buffer
#define PORT 2500   //The port to establish UDP conection

void DieWithError(char *s)
{
perror(s);
exit(1);
}


int main(int argc, char *argv[])
{
char* msg = "HI \n"; 
char buffer[MAXRCVLEN + 1];

int len, consocket;
struct sockaddr_in dest;
struct sockaddr_in serv;
int mysocket;
socklen_t socksize = sizeof(struct sockaddr_in);

memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port = htons(PORTNUM);

mysocket = socket(AF_INET, SOCK_STREAM, 0);

bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
///////////////////////////////////////////////////////////
//UDP initialiazation to forward received message to client
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other), recv_len;
char buf[BUFLEN];
char message[BUFLEN];
int num; //number of messages   

s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

//creates socket
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);

inet_aton(SERVER , &si_other.sin_addr);


    /*{
        DieWithError("sendto() failed");
    }*/


 ///////////////////////////////////////////////////////////

do{
listen(mysocket, 1);
consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
send(consocket, msg, strlen(msg), 0);
    while(len=recv(consocket, buffer, MAXRCVLEN, 0)>0){
            if(strncmp(buffer, "exit", 4) == 0){ 
        break;
    }

           printf("Received: %s ", buffer);
         //checks the received message alpha or digit
            if(isalpha(buf[0])){
        strcpy(buf, "this is not a digit");//sends this message to client 
        //if the message is alphs
        }



           //udp sends function to send the msg using UDP
            if (sendto(s, message, strlen(message) , 0 , (struct sockaddr
   *) &si_other, slen)==-1)
    {
        DieWithError("sendto() failed");
    }
    //clear the buffer
    memset(buf,'\0', BUFLEN);
  //memset(buffer, 0, strlen(buffer));


    }
  printf("Goodbye !\n");
    close(consocket);

}while(consocket);

close(mysocket);
return EXIT_SUCCESS;
}

这是我的transfer.c:

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

#define PORTNUM1 2300
#define PORTNUM2 2400
#define MAXRCVLEN 500


int main(int argc, char *argv[])
{
char* msg = "HI from Inter-server\n"; 
char buffer[MAXRCVLEN + 1];

int len, consocket;
struct sockaddr_in dest;
struct sockaddr_in serv;

struct sockaddr_in client;

int server_socket;
int client_socket;

// For server connection
socklen_t socksize = sizeof(struct sockaddr_in);

memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = htonl(INADDR_ANY);
serv.sin_port = htons(PORTNUM1);
server_socket = socket(AF_INET, SOCK_STREAM, 0);
bind(server_socket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
////////////////////////////////////////////////////////////
//  code for for client connection 
// socket, connect, and recv here
client_socket = socket(AF_INET, SOCK_STREAM, 0);

 memset(&client, 0, sizeof(client));
 client.sin_family = AF_INET;
 client.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 client.sin_port = htons(PORTNUM2);

 connect(client_socket, (struct sockaddr *)&client, sizeof(struct 
 sockaddr));

recv(client_socket, msg, MAXRCVLEN, 0);

///////////////////////////////////////////////////////////


// printf("As a client, I Received %s \n", buffer);
// memset(buffer, 0, strlen(buffer));

printf("Server starts...\n");

do{
listen(server_socket, 1);
consocket = accept(server_socket, (struct sockaddr *)&dest, &socksize);
send(consocket, msg, strlen(msg), 0);
    while(len=recv(consocket, buffer, MAXRCVLEN, 0)>0){
            printf("Received: %s ", buffer);

// As a client, send "buffer" here

           send(client_socket, buffer, strlen(buffer), 0);


           if(strncmp(buffer, "exit", 4) == 0) break;


      memset(buffer, 0, strlen(buffer));

       }
printf("Goodbye !\n");
    close(consocket);

}while(consocket);

close(client_socket);
close(server_socket);
return EXIT_SUCCESS;
}

这是我的client.c:

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

#define MAXRCVLEN 500
#define PORTNUM 2300
#define BUFLEN 512  //Max length of buffer
#define PORT 2500   //The port  to establish UDP connection

void DieWithError(char *s)
{
    perror(s);
exit(1);
}


int main(int argc, char *argv[])
{
char buffer[MAXRCVLEN + 1]; // for receiving
int len, mysocket;
struct sockaddr_in dest;
char msg[MAXRCVLEN + 1]; // for sending

mysocket = socket(AF_INET, SOCK_STREAM, 0);

memset(&dest, 0, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
dest.sin_port = htons(PORTNUM);

connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));
/////////////////////////////////////////////////////////
//UDP initialization 
  struct sockaddr_in si_me, si_other;

  int s, i, slen = sizeof(si_other) , recv_len;
  char message[BUFLEN];
  //int num=0;
  char buf[BUFLEN];
 //create a UDP socket
 if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
    DieWithError("socket() failed");
}

// zero out the structure
memset((char *) &si_me, 0, sizeof(si_me));

si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);

//bind socket to port
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
{
    DieWithError("bind() failed");
}



//check digits or alpha



/////////////////////////////////////////////////////////
len = recv(mysocket, buffer, MAXRCVLEN, 0);
if(len < 0){
    perror("Reciver failed");
    close(mysocket);
    return EXIT_FAILURE;
}
else{
    buffer[len] = '\0';
    printf("I Received %s \n", buffer);
 }


            //printf("Received: %s ", buffer);


 while(1){
    printf("Enter a character ");
    fgets(msg, sizeof(msg), stdin);
    if(strncmp(msg, "exit", 4) == 0) break;
    if(send(mysocket, msg, strlen(msg), 0) < 0){
            perror("Send failed");
            close(mysocket);
            return EXIT_FAILURE;
    }

 memset(msg, 0, strlen(msg));

}
if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other,
&slen)) == -1 )//to receive message from server as UDP
    {
        DieWithError("recvfrom() failed");
    }
  printf("Received a packet from %s:%d\n", inet_ntoa(si_other.sin_addr),
  ntohs(si_other.sin_port));
    printf("Data: %s\n" , buf);

 //printf("Received: %s ", buffer);    
 close(mysocket);
return EXIT_SUCCESS;
}

最佳答案

我认为你的编码风格不好。以下可以工作。

服务器.c

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

#define PORTNUM 2400
#define MAXRCVLEN 500
#define SERVER "127.0.0.1" // local server
#define BUFLEN 512  //Max length of buffer
#define PORT 2500   //The port to establish UDP conection

void DieWithError(char *s)
{
    perror(s);
    exit(1);
}


int main(int argc, char *argv[])
{
    char* msg = "HI \n"; 
    char buffer[MAXRCVLEN + 1];

    int len, consocket;
    struct sockaddr_in dest;
    struct sockaddr_in serv;
    int mysocket;
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(PORTNUM);

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
///////////////////////////////////////////////////////////
//UDP initialiazation to forward received message to client
    struct sockaddr_in si_other;
    int s, i, slen=sizeof(si_other), recv_len;
    char buf[BUFLEN];
    char message[BUFLEN];
    int num; //number of messages   

    s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

//creates socket
    memset((char *) &si_other, 0, sizeof(si_other));
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons(PORT);

    inet_aton(SERVER , &si_other.sin_addr);


    /*{
        DieWithError("sendto() failed");
    }*/


 ///////////////////////////////////////////////////////////

    do{
        listen(mysocket, 1);
        consocket = accept(mysocket, (struct sockaddr *)&dest, &socksize);
        send(consocket, msg, strlen(msg), 0);
            while((len=recv(consocket, buffer, MAXRCVLEN, 0))>0){
                if( strncmp(buffer, "exit", 4) == 0) 
                    break;

            buffer[len] = '\0';
                printf("Received: %s", buffer);
         //checks the received message alpha or digit
                memset(buf,0, BUFLEN);
                    if(isalpha(buffer[0])){
                    strcpy(buf, "this is not a digit");//sends this message to client 
        //if the message is alphs
                }
            else {
                    strcpy(buf, "this is a digit");//sends this message to client 
            }

            //puts(buf);

           //udp sends function to send the msg using UDP
                    if (sendto(s, buf, strlen(buf) , 0 , (struct sockaddr*) &si_other, slen)==-1)
                {
                    DieWithError("sendto() failed");
                }
    //clear the buffer
  //memset(buffer, 0, strlen(buffer));
        }

            close(consocket);

    }while(consocket);

    printf("Goodbye !\n");
    close(mysocket);
    return EXIT_SUCCESS;
}

转移.c

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

#define PORTNUM1 2300
#define PORTNUM2 2400
#define MAXRCVLEN 500


int main(int argc, char *argv[])
{
    char* msg = "HI from Inter-server\n"; 
    char buffer[MAXRCVLEN + 1];

    int len, consocket;
    struct sockaddr_in dest;
    struct sockaddr_in serv;

    struct sockaddr_in client;

    int server_socket;
    int client_socket;

    // For server connection
    socklen_t socksize = sizeof(struct sockaddr_in);

    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(PORTNUM1);
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    bind(server_socket, (struct sockaddr *)&serv, sizeof(struct sockaddr));
    ////////////////////////////////////////////////////////////
    //  code for for client connection 
    // socket, connect, and recv here
    client_socket = socket(AF_INET, SOCK_STREAM, 0);

    memset(&client, 0, sizeof(client));
    client.sin_family = AF_INET;
    client.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    client.sin_port = htons(PORTNUM2);

    connect(client_socket, (struct sockaddr *)&client, sizeof(struct sockaddr));

    recv(client_socket, msg, MAXRCVLEN, 0);

    ///////////////////////////////////////////////////////////


    // printf("As a client, I Received %s \n", buffer);
    // memset(buffer, 0, strlen(buffer));

    printf("Server starts...\n");

    do{
        listen(server_socket, 1);
        consocket = accept(server_socket, (struct sockaddr *)&dest, &socksize);
        send(consocket, msg, strlen(msg), 0);
        while((len=recv(consocket, buffer, MAXRCVLEN, 0))>0){
            printf("Received: %s ", buffer);
    // As a client, send "buffer" here
            send(client_socket, buffer, strlen(buffer), 0);
            if(strncmp(buffer, "exit", 4) == 0) 
                break;
            memset(buffer, 0, strlen(buffer));
        }
        printf("Goodbye !\n");
            close(consocket);
    }while(consocket);

    close(client_socket);
    close(server_socket);

    return EXIT_SUCCESS;
}

客户端.c

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

#define MAXRCVLEN 500
#define PORTNUM 2300
#define BUFLEN 512  //Max length of buffer
#define PORT 2500   //The port  to establish UDP connection

void DieWithError(char *s)
{
        perror(s);
    exit(1);
}


int main(int argc, char *argv[])
{
    char buffer[MAXRCVLEN + 1]; // for receiving
    int len, mysocket;
    struct sockaddr_in dest;
    char msg[MAXRCVLEN + 1]; // for sending

    mysocket = socket(AF_INET, SOCK_STREAM, 0);

    memset(&dest, 0, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    dest.sin_port = htons(PORTNUM);

    connect(mysocket, (struct sockaddr *)&dest, sizeof(struct sockaddr));
/////////////////////////////////////////////////////////
//UDP initialization 
    struct sockaddr_in si_me, si_other;

    int s, i, recv_len;
    socklen_t slen = sizeof(si_other);
    char message[BUFLEN];
  //int num=0;
    char buf[BUFLEN];
 //create a UDP socket
    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
            DieWithError("socket() failed");
    }

// zero out the structure
    memset((char *) &si_me, 0, sizeof(si_me));

    si_me.sin_family = AF_INET;
    si_me.sin_port = htons(PORT);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);

//bind socket to port
    if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
    {
            DieWithError("bind() failed");
    }



//check digits or alpha



/////////////////////////////////////////////////////////
    len = recv(mysocket, buffer, MAXRCVLEN, 0);
    if(len < 0){
            perror("Reciver failed");
            close(mysocket);
            return EXIT_FAILURE;
    }
    else{
            buffer[len] = '\0';
            printf("I Received %s \n", buffer);
    }


            //printf("Received: %s ", buffer);


    while(1){
        memset(msg, 0, sizeof(msg));
            printf("Enter a character ");
            fgets(msg, sizeof(msg), stdin);
            if(strncmp(msg, "exit", 4) == 0) 
            ;
            if(send(mysocket, msg, strlen(msg), 0) < 0){
                    perror("Send failed");
                    close(mysocket);
                    return EXIT_FAILURE;
            }

        if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen)) == -1 )//to receive message from server as UDP
            {
                DieWithError("recvfrom() failed");
            }
        printf("Received a packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); 
        printf("Data: %s\n" , buf);
    }
 //printf("Received: %s ", buffer);    
    close(mysocket);
    return EXIT_SUCCESS;
}

关于c - 在c中使用UDP和TCP套接字编程建立连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43670978/

相关文章:

javascript - 当客户端中止 XHR 请求时,服务器端会发生什么?

http - HTTP 协议(protocol)究竟是如何工作的?

sockets - chrome.socket是否支持多播套接字?

c - 将矩阵文本文件读入c中的数组

当 int 变量在循环内更新时,C 代码不起作用

c - 如何检查数组指针中的元素?

sockets - 将套接字绑定(bind)到本地主机以外的任何地址是什么意思?

c - 使用 scanf 检测整数溢出

c - 错误 : array type has incomplete element type

objective-c - 通过套接字与 ESMTP 协商 TLS