简体   繁体   English

无法发送写在 c 中的简单 UDP 数据包

[英]can not send simple UDP packet written in c

I am a current UNI student learning about socket programming and my first task was to create a simple client server model where the client sends a string and the server transforms it to all caps and returns it.我是一名正在学习套接字编程的 UNI 学生,我的第一个任务是创建一个简单的客户端服务器 model,客户端发送一个字符串,服务器将其转换为全部大写并返回。

I am not getting any errors in my code however when i compile it the server side gets stuck after one iteration of the for loop.我的代码中没有出现任何错误,但是当我编译它时,服务器端在 for 循环的一次迭代后卡住了。

here is the server side code:这是服务器端代码:

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define BUF_LEN 48


//this function will convert string into upper case 
int processString(char *input, char *output){

int len = strlen(input);
for (int i=0;i<len;i++){
output[i] = toupper(input[i]); 
}
output[len]='\0';
return len;
}




int main(int argc,char *argv[]){
/* ----------------------------DECLARING VARIABLES----------------------------------   */
int ssd;                    
struct sockaddr_in server;  //server info
struct sockaddr_in client;  //client info       
int client_len;  // size of client          
short echo_port; // the port number           
int max_iterations; // usually runs forever but this will limit server        
int byteInCount,byteOutCount,recieveCount,i;
char clientString[BUF_LEN];
char serverProcessedString[BUF_LEN];
int retCode;

/* ----------------------------END: DECLARING VARIABLES----------------------------------   */



/* ---------------------------CHECKING THE COMMAND LINE----------------------------   */

if (argc != 3)
{
    fprintf(stderr,"incorrect usage! %s port Max_iterations\n",argv[0]);
    exit(EXIT_FAILURE);
}
echo_port = atoi(argv[1]);
max_iterations = atoi(argv[2]);

/* ---------------------------END: CHECKING THE COMMAND LINE----------------------------   */



/* ----------------------------CREATE THE SOCKET CONNECTION----------------------------------   */
ssd = socket(PF_INET,SOCK_DGRAM,0); // refer to notes about meaning of each parameter
if (ssd <0){
perror("error in function socket()\n");
exit(EXIT_FAILURE);
}

server.sin_family=AF_INET; // ip protocol 
server.sin_addr.s_addr=htonl(INADDR_ANY);
server.sin_port= htonl(echo_port); // port to serve on

retCode = bind(ssd,(struct sockaddr *)&server,sizeof(server)); // ask tut about bind() function
if (retCode <0)
{
    perror("error in function bind()\n");
    exit(EXIT_FAILURE);
}
/* ----------------------------END: CREATE THE SOCKET CONNECTION----------------------------------   */


/* ---------------------------- START THE SERVER----------------------------------   */
for (int i=0;i<max_iterations;i++){
fprintf(stderr,"Iteration %d of %d. Waiting for client...\n",i+1, max_iterations);
client_len = sizeof(client);
byteInCount = recvfrom(ssd,clientString,BUF_LEN,0,(struct sockaddr *)&client,(socklen_t *)&client_len);
if (byteInCount <0)
{
    perror("error in function revfrom()\n");
    exit(EXIT_FAILURE);
}
else{
fprintf(stderr,"revfrom() is all g\n");
}
fprintf(stderr,"Reversed string is %d bytes long\n", recieveCount);
fprintf(stderr,"Reversed string is \"%s\"\n",serverProcessedString);
byteOutCount = sendto(ssd,serverProcessedString,recieveCount+1,0,(struct sockaddr *)&client,sizeof(client));
if (byteOutCount <0){
    perror("error in function sendto()\n");
    exit(EXIT_FAILURE);
}
fprintf(stderr,"client request worked, reply has been sent\n");


}
close(ssd);
fprintf(stderr,"server has shutdown!\n");

return 0;


}

and this is the client side code:这是客户端代码:

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define BUF_LEN 48

int main(int argc,char *argv[]){
int csd;
struct sockaddr_in server;
struct hostent *server_host;
int serverLength;
int stringSize;
short serverPort;
int byteInCount,byteOutCount;
char clientString[BUF_LEN];
char serverProcessedString[BUF_LEN];

if (argc != 4){
    fprintf(stderr,"usage: %s server port send_string \n",argv[0]);
    exit(EXIT_FAILURE);
}

server_host =gethostbyname(argv[1]);
if (server_host== NULL){
herror("error in function gethostbyname()\n"); // ask tut- this function is no longer used( getaddrinfo)
exit(EXIT_FAILURE);
}

serverPort= atoi(argv[2]);
strcpy(clientString,argv[3]);


csd = socket(PF_INET,SOCK_DGRAM,0);
if(csd <0)
{
    perror("error in function socket()");
    exit(EXIT_FAILURE);
}
server.sin_family= AF_INET;
memcpy(&server.sin_addr.s_addr,server_host->h_addr_list[0],server_host->h_length); // ask tut about this function
server.sin_port=htons(serverPort); // difference between htons and htonl???
stringSize=strlen(clientString)+1;
byteOutCount= sendto(csd,clientString,stringSize,0,(struct sockaddr *)&server,sizeof(server));

if (byteOutCount <0){
    perror("error in function sendto()\n");
    exit(EXIT_FAILURE);
}

fprintf(stderr,"You have sent \"%s\"\n",clientString);
fprintf(stderr,"Have reached recvfrom(), should now block until message receipt\n");

//get the response from server
serverLength = sizeof(server);
byteInCount = recvfrom(csd,serverProcessedString,BUF_LEN,0,(struct sockaddr *)&server,(socklen_t)&serverLength);

if (byteInCount <0){
    perror("error in function recvfrom()\n");
    exit(EXIT_FAILURE);
}
fprintf(stderr,"the server has responded with: : \"%s\"\n",serverProcessedString);
close(csd);

return 0;
}

i am compiling this on a Ubuntu VM: terminal 1我正在 Ubuntu VM 上编译它:终端 1

cc UDP_client.c -o send
./send 192.168.0.1 9999 hello

(the ip address above was obtained using the ifconfig command) (上面的ip地址是使用ifconfig命令获取的)

terminal 2 2号航站楼

cc UDP_server.c -o rec
./rec 9999 10

my current output:我当前的 output:

terminal 2 2号航站楼

"Iteration 1 of 10. waiting for client" “迭代 1 次,共 10 次。等待客户”

terminal 1: 1号航站楼:

"you have sent hello" “你打招呼了”

"have reached recvfrom(),should now block until message receipt" “已经到达 recvfrom(),现在应该阻塞直到收到消息”

it seems like a problem with my loop?我的循环似乎有问题? any help would be appreciated.任何帮助,将不胜感激。

EDIT: after fixing the error in the comments below, on the client side i am receiving an error in the recvfrom function: error says, bad address?编辑:修复下面评论中的错误后,在客户端,我在 recvfrom function 中收到错误:错误说,地址错误?

I found a few issues in your code.我在您的代码中发现了一些问题。

  1. make sure the struct sockaddr_in server and client should be memset to zero.确保 struct sockaddr_in 服务器和客户端应 memset 为零。 As these are local variables and can have invalid values因为这些是局部变量并且可以具有无效值
  2. In your server, you did not call processString() before calling sendto.在您的服务器中,您在调用 sendto 之前没有调用 processString()。
  3. Your compilation should have zero warnings, that way you would have fixed a lot of inherent issues您的编译应该有零警告,这样您就可以解决很多固有问题
  4. Indenting code really helps in readability and maintainability.缩进代码确实有助于提高可读性和可维护性。
  5. added a couple of required headers (unistd and stdlib.h)添加了几个必需的标头(unistd 和 stdlib.h)
  6. initialized the address to INADDR_ANY in both client and server and htons for port在客户端和服务器中将地址初始化为 INADDR_ANY,并为端口初始化 htons
  7. One recommendation, please initialize all local variables to zeros to avoid any unexpected result.一个建议,请将所有局部变量初始化为零以避免任何意外结果。

here is the server code (note, I kept your original code as close to what it was, with minor fixes to make it work, please test thoroughly)这是服务器代码(请注意,我将您的原始代码保持在接近原来的状态,并进行了一些小的修复以使其正常工作,请彻底测试)

#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#define BUF_LEN 48


//this function will convert string into upper case 
int processString(char *input, char *output){

    int len = strlen(input);
    for (int i=0;i<len;i++){
        output[i] = toupper(input[i]); 
    }
    output[len]='\0';
    return len;
}




int main(int argc,char *argv[]){
    /* ----------------------------DECLARING VARIABLES----------------------------------   */
    int ssd;                    
    struct sockaddr_in server;  //server info
    struct sockaddr_in client;  //client info       
    int client_len;  // size of client          
    short echo_port; // the port number           
    int max_iterations; // usually runs forever but this will limit server        
    int byteInCount,byteOutCount,recieveCount,i;
    char clientString[BUF_LEN];
    char serverProcessedString[BUF_LEN];
    int retCode;

    /* ----------------------------END: DECLARING VARIABLES----------------------------------   */



    /* ---------------------------CHECKING THE COMMAND LINE----------------------------   */

    if (argc != 3)
    {
        fprintf(stderr,"incorrect usage! %s port Max_iterations\n",argv[0]);
        exit(EXIT_FAILURE);
    }
    echo_port = atoi(argv[1]);
    max_iterations = atoi(argv[2]);

    /* ---------------------------END: CHECKING THE COMMAND LINE----------------------------   */



    /* ----------------------------CREATE THE SOCKET CONNECTION----------------------------------   */
    ssd = socket(AF_INET, SOCK_DGRAM, 0); // refer to notes about meaning of each parameter
    if (ssd <0){
        perror("error in function socket()\n");
        exit(EXIT_FAILURE);
    }

    memset(&server, 0, sizeof(server)); 
    memset(&client, 0, sizeof(client)); 

    server.sin_family=AF_INET; // ip protocol 
    server.sin_addr.s_addr=htonl(INADDR_ANY);
    server.sin_port= htons(echo_port); // port to serve on

    retCode = bind(ssd,(struct sockaddr *)&server,sizeof(server)); // ask tut about bind() function
    if (retCode <0)
    {
        perror("error in function bind()\n");
        exit(EXIT_FAILURE);
    }
    /* ----------------------------END: CREATE THE SOCKET CONNECTION----------------------------------   */


    /* ---------------------------- START THE SERVER----------------------------------   */
    for (int i=0;i<max_iterations;i++){
        fprintf(stderr,"Iteration %d of %d. Waiting for client...\n",i+1, max_iterations);
        client_len = sizeof(client);
        byteInCount = recvfrom(ssd, clientString, BUF_LEN,
                               MSG_WAITALL, (struct sockaddr *)&client, 
                               (socklen_t *)&client_len);
        if (byteInCount <0)
        {
            perror("error in function revfrom()\n");
            exit(EXIT_FAILURE);
        }
        else{
            fprintf(stderr,"revfrom() is all g\n");
        }
        recieveCount = processString(clientString, serverProcessedString);
        fprintf(stderr,"Reversed string is %d bytes long\n", recieveCount);
        fprintf(stderr,"Reversed string is \"%s\"\n",serverProcessedString);
        byteOutCount = sendto(ssd, serverProcessedString, recieveCount+1, 0, 
                              (struct sockaddr *)&client,sizeof(client));
        if (byteOutCount <0){
            perror("error in function sendto()\n");
            exit(EXIT_FAILURE);
        }
        fprintf(stderr,"client request worked, reply has been sent\n");

    }
    close(ssd);
    fprintf(stderr,"server has shutdown!\n");

    return 0;


}

here is your client code这是您的客户端代码

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

#define BUF_LEN 48

int main(int argc,char *argv[]){
    int csd;
    struct sockaddr_in server;
    struct hostent *server_host;
    int serverLength;
    int stringSize;
    short serverPort;
    int byteInCount,byteOutCount;
    char clientString[BUF_LEN];
    char serverProcessedString[BUF_LEN];

    if (argc != 4){
        fprintf(stderr,"usage: %s server port send_string \n",argv[0]);
        exit(EXIT_FAILURE);
    }

    server_host =gethostbyname(argv[1]);
    if (server_host== NULL){
        herror("error in function gethostbyname()\n"); // ask tut- this function is no longer used( getaddrinfo)
        exit(EXIT_FAILURE);
    }

    serverPort= atoi(argv[2]);
    strcpy(clientString,argv[3]);


    csd = socket(AF_INET, SOCK_DGRAM, 0);
    if(csd <0)
    {
        perror("error in function socket()");
        exit(EXIT_FAILURE);
    }
    memset(&server, 0, sizeof(server));

    server.sin_family= AF_INET;
    //memcpy(&server.sin_addr.s_addr,server_host->h_addr_list[0],server_host->h_length); // ask tut about this function
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(serverPort); // difference between htons and htonl???
     
    stringSize = strlen(clientString)+1;
    byteOutCount= sendto(csd, clientString, stringSize,
                         MSG_CONFIRM, (struct sockaddr *)&server, 
                         sizeof(server));

    if (byteOutCount <0){
        perror("error in function sendto()\n");
        exit(EXIT_FAILURE);
    }

    fprintf(stderr,"You have sent \"%s\"\n",clientString);
    fprintf(stderr,"Have reached recvfrom(), should now block until message receipt\n");

    //get the response from server
    serverLength = sizeof(server);
    byteInCount = recvfrom(csd, serverProcessedString, BUF_LEN,
                           MSG_WAITALL, (struct sockaddr *)&server,
                           (socklen_t *) &serverLength);

    if (byteInCount <0){
        perror("error in function recvfrom()\n");
        exit(EXIT_FAILURE);
    }
    fprintf(stderr,"the server has responded with: : \"%s\"\n",serverProcessedString);
    close(csd);

    return 0;
}

In one terminal, run./server 9999 10在一个终端中,运行./server 9999 10

In another terminal run./client localhost 9999 hello在另一个终端运行./client localhost 9999 hello

Output on Server side服务器端 Output

Iteration 1 of 10. Waiting for client...
revfrom() is all g
Reversed string is 5 bytes long
Reversed string is "HELLO"
client request worked, reply has been sent
Iteration 2 of 10. Waiting for client...

Output on client side Output 在客户端

You have sent "hello"
Have reached recvfrom(), should now block until message receipt
the server has responded with: : "HELLO"

All the best.祝一切顺利。 I haven't bug checked your code, ensure processString is working fine.我没有检查过你的代码,确保 processString 工作正常。 All the best!祝一切顺利!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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