gpt4 book ai didi

c - c语言udp套接字编程问题

转载 作者:行者123 更新时间:2023-11-30 15:54:42 24 4
gpt4 key购买 nike

我编译了以下UDP客户端的C代码在终端中运行“./udpclient localhost 9191”后。我将“Enter Text=”设置为“Hello”,但在 sendto 中显示错误,如下所示:

Enter text: hello 
hello
: error in sendto()guest-1SDRJ2@md-K42F:~/Desktop$

"

注意:我在其他终端中打开第一个服务器端口,如下所示./服务器9191。我相信服务器代码没有错误。 udp 客户端未将消息传递到服务器。如果我不使用线程,消息就会传递。但我必须通过线程来传递消息。

UDP客户端代码:

/* simple UDP echo client */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <pthread.h>

#define STRLEN 1024

static void *readdata(void *);
static void *writedata(void *);
int sockfd, n, slen;
struct sockaddr_in servaddr;
char sendline[STRLEN], recvline[STRLEN];

int main(int argc, char *argv[]) {
pthread_t readid,writeid;

struct sockaddr_in servaddr;
struct hostent *h;

if(argc != 3) {
printf("Usage: %s <proxy server ip> <port>\n", argv[0]);
exit(0);
}

/* create hostent structure from user entered host name*/
if ( (h = gethostbyname(argv[1])) == NULL) {
printf("\n%s: error in gethostbyname()", argv[0]);
exit(0);
}

/* create server address structure */
bzero(&servaddr, sizeof(servaddr)); /* initialize it */
servaddr.sin_family = AF_INET;
memcpy((char *) &servaddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
servaddr.sin_port = htons(atoi(argv[2])); /* get the port number from argv[2]*/

/* create a UDP socket: SOCK_DGRAM */
if ( (sockfd = socket(AF_INET,SOCK_DGRAM, 0)) < 0) {
printf("\n%s: error in socket()", argv[0]);
exit(0);
}


pthread_create(&readid,NULL,&readdata,NULL);
pthread_create(&writeid,NULL,&writedata,NULL);

while(1)
{
};

close(sockfd);
}

static void * writedata(void *arg)
{
/* get user input */
printf("\nEnter text: ");

do {
if (fgets(sendline, STRLEN, stdin) == NULL) {
printf("\n%s: error in fgets()");
exit(0);
}
/* send a text */
if (sendto(sockfd, sendline, sizeof(sendline), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
printf("\n%s: error in sendto()");
exit(0);
}
}while(1);
}

static void * readdata(void *arg)
{
/* wait for echo */
slen = sizeof(servaddr);
if ( (n = recvfrom(sockfd, recvline, STRLEN, 0, (struct sockaddr *) &servaddr, &slen)) < 0) {
printf("\n%s: error in recvfrom()");
exit(0);
}

/* null terminate the string */
recvline[n] = 0;

fputs(recvline, stdout);


}

最佳答案

问题是您使用的是相同的 sockaddr servaddr 的结构 ( sendto )和revfrom来电。 recvfrom首先发生,所以它清除 servaddr准备写入接收到的数据包的源地址(一旦接收到数据包,该线程仍被阻塞在内核中等待数据包)。然后,当 sendto发生调用时,sockaddr全部为零,因此它立即返回 EINVAL。

您可能会对sockaddr这一事实感到困惑。 recvfrom 的参数是一个输出,而不是输入——它被接收到的数据包的源地址填充(可以来自任何地方)。如果您只想接收来自特定位置(服务器?)的数据包,则需要检查recvfrom后面的地址。如果数据包来自其他地方,则返回并丢弃该数据包,循环回到 recvfrom再次。

关于c - c语言udp套接字编程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12785266/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com