[英]Problem in udp socket programing in c
在终端中运行“ ./udpclient localhost 9191”后,我编译了以下UDP客户端的C代码。我将“ Enter Text =”作为Hello,但在sendto中显示错误,如下所示:
Enter text: hello
hello
: error in sendto()guest-1SDRJ2@md-K42F:~/Desktop$
”
注意:我在其他终端./server 9191中打开如下所示的1st服务器端口。我相信服务器代码中没有错误。 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);
}
问题是您对sendto
和revfrom
调用都使用了相同的sockaddr
结构( servaddr
)。 recvfrom
首先发生,因此它会清除servaddr
以准备写入接收到的压缩包的源地址(一旦接收到它-线程仍在内核中阻塞,等待数据包)。 然后,当发生sendto
调用时, sockaddr
都为零,因此它立即返回EINVAL。
您可以通过以下事实可以感到困惑sockaddr
参数recvfrom
是输出,而不是输入-它被与接收数据包(可以从任何地方)的源地址填写。 如果您只想接收来自特定位置(服务器?)的数据包,则需要在recvfrom
返回后检查地址,如果数据包来自其他地方,则将其扔掉,然后再次循环回到recvfrom
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.