gpt4 book ai didi

c - TCP 上的可变长度消息

转载 作者:行者123 更新时间:2023-11-30 17:05:43 25 4
gpt4 key购买 nike

我正在尝试在 TCP 中发送可变长度消息,但消息长度
打印的总是0。我使用beej引导代码进行发送和接收以及打包和解包来发送 header 长度。有人可以指出错误吗?

服务器代码

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

#define MAX_SIZE 50

void error(const char *msg)
{
perror(msg);
exit(1);
}


void packi32(unsigned char *buf, unsigned long i)//from beej guide
{
*buf++ = i>>24; *buf++ = i>>16;
*buf++ = i>>8; *buf++ = i;
}

/* sends all data - thanks to Beej's Guide to Network Programming */
int sendall(int s, char *buf, int *len)
{
int total=0;
int bytesleft=*len;
int n=0;

/* send all the data */
while(total<*len){

/* send some data */
n=send(s,buf+total,bytesleft,0);

/* break on error */
if(n==-1)
break;

/* apply bytes we sent */
total+=n;
bytesleft-=n;
}

/* return number of bytes actually send here */
*len=total;

/* return -1 on failure, 0 on success */
return n==-1?-1:0;
}

int sendus(int s,char *msg)
{
char buf[4];//here 4 is header length
int len = strlen(msg);
packi32(buf,len);
int ll = 4;// ll is header length containing message length
int x;
if((x = sendall(s,buf,&ll))< 0)
printf("value of sent x %d\n",x);

int y = sendall(s,msg,&len);
return y;
}

int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;

if (argc < 2)
{
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);

if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");

listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);


if (newsockfd < 0)
error("ERROR on accept");

char msg[1024] = "hello";
int xx = sendus(sockfd,(char*)msg);


close(newsockfd);

close(sockfd);
return 0;
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<errno.h>
void error(const char *msg)
{
perror(msg);
exit(0);
}

/** unpacki32() -- unpack a 32-bit int from a char buffer (like ntohl())
*/
unsigned long unpacki32(unsigned char *buf)
{
return (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
}

/* receives all data - modelled after sendall() */
int recvall(int s, char *buf, int *len, int timeout){
int total=0;
int bytesleft=*len;
int n=0;
time_t start_time;
time_t current_time;

/* clear the receive buffer */
bzero(buf,*len);

time(&start_time);

/* receive all data */
while(total<*len){

/* receive some data */
n=recv(s,buf+total,bytesleft,0);

/* no data has arrived yet (non-blocking socket) */
if(n==-1 && errno==EAGAIN){
time(&current_time);
if(current_time-start_time>timeout)
break;
sleep(1);
continue;
}

/* receive error or client disconnect */
else if(n<=0)
break;

/* apply bytes we received */
total+=n;
bytesleft-=n;
}

/* return number of bytes actually received here */
*len=total;

/* return <=0 on failure, bytes received on success */
return (n<=0)?n:total;
}

int recvme(int s, char *buf)
{
char len[4];
int l = 4;
int n = recvall(s,len,&l,10);
int msg_len = unpacki32(len);
printf("msg_length :%d",msg_len);

int z ;
z = recvall(s,buf,&msg_len,10);

return z;
}

int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;

char buffer[1024];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");

server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);

serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n = recvme(sockfd, buffer);
if (n < 0)
error("ERROR reading from socket");


printf("%s\n",buffer);

close(sockfd);
return 0;
}

最佳答案

失败的根本原因在服务器线路

int xx = sendus(sockfd,(char*)msg);

-sockfdlisten()套接字,但我们必须使用 newsockfdaccept() 返回, 我。 e.

    sendus(newsockfd, msg);

关于c - TCP 上的可变长度消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35127995/

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