C UDP服务器没有响应客户端
正在开发一个旨在模拟网络中的数据层的程序。我已经正确地将消息发送到服务器,但是,客户端没有从服务器接收到ACK帧。这导致我的程序无休止地等待。如能帮助解决此事,我们将不胜感激 寄件人C UDP服务器没有响应客户端,c,udp,C,Udp,正在开发一个旨在模拟网络中的数据层的程序。我已经正确地将消息发送到服务器,但是,客户端没有从服务器接收到ACK帧。这导致我的程序无休止地等待。如能帮助解决此事,我们将不胜感激 寄件人 #include <stdio.h> #include <unistd.h> #define MAXFRAME 97 main(int argc, char* argv[]){ char *frame; int len = 0; int c; dlinits
#include <stdio.h>
#include <unistd.h>
#define MAXFRAME 97
main(int argc, char* argv[]){
char *frame;
int len = 0;
int c;
dlinits("spirit.cba.csuohio.edu", 43525);
frame = malloc(MAXFRAME);
FILE *file = fopen(argv[1], "r");
if (file == NULL)
return NULL;
while ((c = fgetc(file)) != EOF)
{
if(len == (MAXFRAME-1)){
dlsend(frame, len, 0);
len = 0;
memset(frame,0,strlen(frame));
}
frame[len++] = (char) c;
}
dlsend(frame, len, 1);
}
#包括
#包括
#定义MAXFRAME 97
main(int argc,char*argv[]){
字符*帧;
int len=0;
INTC;
dlinits(“spirit.cba.csuohio.edu”,43525);
帧=malloc(MAXFRAME);
FILE*FILE=fopen(argv[1],“r”);
if(file==NULL)
返回NULL;
而((c=fgetc(文件))!=EOF)
{
如果(len==(MAXFRAME-1)){
dlsend(帧,len,0);
len=0;
memset(帧,0,strlen(帧));
}
帧[len++]=(char)c;
}
dlsend(帧,len,1);
}
接受者
#include <string.h>
#include <unistd.h>
char* dlrecv();
main(){
char* test[100];
dlinitr(43525);
while(1){
strcpy(test,dlrecv());
printf("%s\n", test);
}
}
#包括
#包括
char*dlrecv();
main(){
字符*测试[100];
dlinitr(43525);
而(1){
strcpy(test,dlrecv());
printf(“%s\n”,测试);
}
}
数据层
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define BUFMAX 100
static int sk;
static struct sockaddr_in remote;
static struct sockaddr_in local;
static int fnum = 0;
static expFra = 0x00;
dlinits(char* host, int port){//initialize sender
struct hostent *hp;
sk = socket(AF_INET, SOCK_DGRAM, 0);
remote.sin_family = AF_INET;
hp = gethostbyname(host);
if (hp == NULL){
printf("Can't find host name\n");
exit(1);
}
bcopy(hp->h_addr,&remote.sin_addr.s_addr,hp->h_length);
remote.sin_port = ntohs(port);
}
dlinitr(int port){//initialize receiver
int rlen = sizeof(remote);
int len = sizeof(local);
char buf[BUFMAX];
sk = socket(AF_INET,SOCK_DGRAM,0);
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(port);
bind (sk, &local,sizeof(local));
getsockname(sk,&local,&len);
}
dlsend(char* msg, int len, int end){//send data
int header = 0x00;
int result;
char *ackframe = malloc(3);
unsigned char *nmsg;
nmsg = malloc(100);
if ((fnum%2) == 1){
header = header|0x02;
}
if (end == 1){
header = header|0x40;
}
header = header^0xff;
printf("%x\n %x\n", header, 0);
nmsg[0] = (char)header;
len++;
printf("%s\n", nmsg);
memcpy(nmsg + 1, msg, strlen(msg));
result = crc(nmsg, len);
nmsg[len++] = ((result >> 8) & 0xff);
nmsg[len++] = (result & 0xff);
printf("%s\n", nmsg);
sendto(sk,nmsg,len,0,&remote,sizeof(remote));
read(sk,ackframe,3);
printf("Ack Received: %s\n", ackframe);
fnum++;
}
char* dlrecv(){//receive data
int result;
int header;
int ACK = 1;
char alen = 1;
char *ackframe = malloc(3);
unsigned char* msg = malloc(100);
while (ACK){
recvfrom(sk,msg,BUFMAX,0,&remote,sizeof(remote));
int len = strlen(msg);
result = crc(msg, len);
if (result == 0){
msg[--len] = 0;
msg[--len] = 0;
header = msg[0];
printf("Header %x expFra %x\n", header, expFra);
header = header^0xff;
printf("Header %x expFra %x\n", header, expFra);
if ((header<<4) == (expFra<<4)){
expFra = expFra^0x02;
ackframe[0] = (0x10|header);
result = crc(ackframe, alen);
ackframe[alen++] = ((result >> 8) & 0xff);
ackframe[alen++] = (result & 0xff);
sendto(sk,ackframe,strlen(ackframe),0,&remote,sizeof(remote));
printf("Ack Sent: %s\n", ackframe);
ACK = 0;
}
}
}
printf("%s\n", msg);
return ++msg;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义BUFMAX 100
静态int-sk;
远程中的静态结构sockaddr_;
本地的静态结构sockaddr_;
静态int fnum=0;
静态expFra=0x00;
dlinits(char*主机,int端口){//初始化发送方
结构主机*hp;
sk=插座(AF_INET,SOCK_DGRAM,0);
remote.sin_family=AF_INET;
hp=gethostbyname(主机);
如果(hp==NULL){
printf(“找不到主机名\n”);
出口(1);
}
b复制(hp->h\u addr和remote.sin\u addr.s\u addr,hp->h\u length);
remote.sin_port=ntohs(端口);
}
dlinitr(int端口){//初始化接收器
int rlen=sizeof(远程);
int len=sizeof(本地);
char buf[BUFMAX];
sk=插座(AF_INET,SOCK_DGRAM,0);
local.sin_family=AF_INET;
local.sin\u addr.s\u addr=INADDR\u ANY;
local.sin_port=htons(port);
绑定(sk和local,sizeof(local));
getsockname(sk、本地和len);
}
dlsend(char*msg,int len,int end){//send data
int头=0x00;
int结果;
char*ackframe=malloc(3);
无符号字符*nmsg;
nmsg=malloc(100);
如果((fnum%2)==1){
收割台=收割台| 0x02;
}
如果(结束==1){
收割台=收割台| 0x40;
}
页眉=页眉^0xff;
printf(“%x\n%x\n”,头,0);
nmsg[0]=(char)头;
len++;
printf(“%s\n”,nmsg);
memcpy(nmsg+1,msg,strlen(msg));
结果=crc(nmsg,len);
nmsg[len++]=(结果>>8)和0xff;
nmsg[len++]=(结果&0xff);
printf(“%s\n”,nmsg);
发送到(sk、nmsg、len、0和remote、sizeof(remote));
读取(sk,ackframe,3);
printf(“收到的确认:%s\n”,确认帧);
fnum++;
}
char*dlrecv(){//接收数据
int结果;
int头;
int ACK=1;
char-alen=1;
char*ackframe=malloc(3);
无符号字符*msg=malloc(100);
while(ACK){
recvfrom(sk、msg、BUFMAX、0和remote、sizeof(remote));
int len=strlen(msg);
结果=crc(msg,len);
如果(结果==0){
msg[--len]=0;
msg[--len]=0;
header=msg[0];
printf(“头%x expFra%x\n”,头,expFra);
页眉=页眉^0xff;
printf(“头%x expFra%x\n”,头,expFra);
如果((header我对UDP的经验是,read()
(您在dlsend()
末尾使用的)是非常偶然的,特别是当与sendto()
配对时。除非有充分的理由不这样做,否则将read()
更改为recvfrom()
应该可以解决问题
你的代码也会对不匹配的类型抛出很多警告。它们有点无害,但会使跟踪其他类型变得更加复杂
在这之后,最后的确认-sendto()
使用了错误的套接字数据。拨弄一下,原因是您在(sizeof(remote)
)中传递了一个整数,作为上一次recvfrom()
调用中地址大小的指针。如果给定的初始大小太小,recvfrom()
产生不可靠的结果。如果它需要的空间小于此值,它将更改该值以告诉您它使用了什么
因此,您需要在
结构中声明一个初始化为sockaddr\u大小的整数,并将指向该整数的指针作为最后一个参数传递给它,您将获得地址的正确值,并能够发送确认
学到的重要经验应该是:(a)确保所有类型都正确,并检查每个警告;(b)检查每个套接字调用的返回值,如果返回-1
,则打印错误。您能谈谈您是如何运行这些程序的吗?它们是否在同一台机器(本地主机)上运行还是涉及多台机器?UDP传输不受保证,大多数防火墙都会丢弃此类流量等。因此,关于您的网络拓扑的一些信息是有保证的。每次我看到strlen()在网络代码中,我变得非常紧张…我做了建议的更改,但结果是一样的。在第一条消息之后,我仍然挂起,因为发件人没有收到任何消息。啊…我还没有找到它,但是remote
在某个地方被破坏了。您会收到一个无效参数
错误,如果您选中ksin_family
和sin_port
,它们被归零了。我明白了。我正在寻找,但我似乎找不到发生这种情况的原因。我想我设法把它全部运行了下来。我会发布代码,但为了调试的目的,我做了很多更改,它与您原来的过程并不太相似。如果您需要更多的c,请随时询问我真的很感谢你的帮助,是的,再澄清一下就好了