recv() 函数用于在一个字符串中获取 while 缓冲区的标志 [windows C]
此代码可以完美地发送和接收 txt 文件,但无法处理 .exe 或 .img 等其他格式。请帮助我解决这些问题,因为我需要使用 htonl 或 htons? 看看吧!
这是服务器端的recv函数::
if (socket_type != SOCK_DGRAM)
{
fi = fopen (final,"wb");
retval = recv(msgsock, recv_buf, strlen(recv_buf), 0);
/*recv_buf[retval] = '\0';
fprintf (fi,"%s",recv_buf);*/
int i;
i=atoi(recv_buf);
char *q;
q=(char *)malloc(i*sizeof(char));
retval = recv(msgsock, q, strlen(q), 0);
//printf ("%s",q);
fwrite(q,i,1,fi);
fclose(fi);
}
else
{
retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen);
printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr));
printf ("SOCK_DGRAM");
}
if (retval == SOCKET_ERROR)
{
fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError());
closesocket(msgsock);
//continue;
}
else
printf("Server: recv() is OK.\n");
if (retval == 0)
{
printf("Server: Client closed connection.\n");
closesocket(msgsock);
//continue;
}
printf("Server: Received %d bytes, data from client\n", retval);
The client side sending function :::
void send_command()
{
int bytesent;
FILE *file_out;
//file_out = fopen(file_path,"rb");
char str_all[100000];//flag [30]="end";
///////////////////////getsize//////////////
char fsize[5];
int filesize;
file_out = fopen(file_path, "rb");
fseek(file_out, 0, SEEK_END);
filesize = ftell(file_out);
rewind (file_out);
itoa (filesize,fsize,10);
/////////////////////////////////////////////
send (ConnectSocket, fsize, strlen (fsize), 0);
char *r = (char *)malloc (filesize * sizeof(char));
fread(r,filesize,1,file_out);
bytesent = send( ConnectSocket, r, strlen(r), 0 );
printf("\nClient: Bytes sent: %ld\n", bytesent);
fclose (file_out);
/*while (fscanf(file_out,"%s",&str_all) != EOF)
{
bytesent = send( ConnectSocket, str_all, strlen(str_all), 0 );
printf("\nClient: Bytes sent: %ld\n", bytesent);
//Sleep(500);
}*/
/*printf("%s",flag);
send( ConnectSocket, flag, strlen(flag), 0 );*/
WSACleanup();
//return 0;
}
This code sends and recv s txt file perfectly but cannot do it to otehr formats like .exe or .img. Please help me with these as I need to use htonl or htons??
Take a look!!
Here is the server side recv function ::
if (socket_type != SOCK_DGRAM)
{
fi = fopen (final,"wb");
retval = recv(msgsock, recv_buf, strlen(recv_buf), 0);
/*recv_buf[retval] = '\0';
fprintf (fi,"%s",recv_buf);*/
int i;
i=atoi(recv_buf);
char *q;
q=(char *)malloc(i*sizeof(char));
retval = recv(msgsock, q, strlen(q), 0);
//printf ("%s",q);
fwrite(q,i,1,fi);
fclose(fi);
}
else
{
retval = recvfrom(msgsock,recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&from, &fromlen);
printf("Server: Received datagram from %s\n", inet_ntoa(from.sin_addr));
printf ("SOCK_DGRAM");
}
if (retval == SOCKET_ERROR)
{
fprintf(stderr,"Server: recv() failed: error %d\n", WSAGetLastError());
closesocket(msgsock);
//continue;
}
else
printf("Server: recv() is OK.\n");
if (retval == 0)
{
printf("Server: Client closed connection.\n");
closesocket(msgsock);
//continue;
}
printf("Server: Received %d bytes, data from client\n", retval);
The client side sending function :::
void send_command()
{
int bytesent;
FILE *file_out;
//file_out = fopen(file_path,"rb");
char str_all[100000];//flag [30]="end";
///////////////////////getsize//////////////
char fsize[5];
int filesize;
file_out = fopen(file_path, "rb");
fseek(file_out, 0, SEEK_END);
filesize = ftell(file_out);
rewind (file_out);
itoa (filesize,fsize,10);
/////////////////////////////////////////////
send (ConnectSocket, fsize, strlen (fsize), 0);
char *r = (char *)malloc (filesize * sizeof(char));
fread(r,filesize,1,file_out);
bytesent = send( ConnectSocket, r, strlen(r), 0 );
printf("\nClient: Bytes sent: %ld\n", bytesent);
fclose (file_out);
/*while (fscanf(file_out,"%s",&str_all) != EOF)
{
bytesent = send( ConnectSocket, str_all, strlen(str_all), 0 );
printf("\nClient: Bytes sent: %ld\n", bytesent);
//Sleep(500);
}*/
/*printf("%s",flag);
send( ConnectSocket, flag, strlen(flag), 0 );*/
WSACleanup();
//return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,您的程序存在多个问题。
char
的所有可能值都是合法的数据值。如果您发送文本数据,您可以说0
表示数据结束,但现在不能。因此,您必须决定服务器和客户端之间的“协议” - 最简单的是服务器发送前 4 个字节中的数据长度(在ntonl()
上读取并ntohl()
了解如何可移植地执行此操作)。然后,接收方将确切地知道要读取多少字节。char *recv_buf
,对于recv_buf1
也是如此。您没有为两个指针中的任何一个分配任何存储空间,因此它们没有指向任何有用的地方。然后,您的recv
调用是:recv(msgsock, recv_buf, sizeof(recv_buf), 0);
这也有问题。第一个是上面提到的:您没有用于recv_buf
的存储空间。第二个是,在为recv_buf
分配存储空间之后,您将获取 char 指针的大小,而不是缓冲区recv
的长度指向.解决这两个问题的一种简单方法是将recv_buf
声明为:char recv_buf[SIZE];
,然后在recv_buf
中使用sizeof recv_buf
代码>recv() 调用。我没有看过你其余的代码。您可能需要良好的 C 和网络编程介绍。
OK, there are multiple issues with your program.
char
are legal data values. If you were sending text data, you could say that a0
signifies the end of the data, but now you can't. So, you have to decide on a "protocol" between the server and the client—the simplest is that the server sends the length of the data in the first 4 bytes (read up onntonl()
andntohl()
for how to do this portably). Then, the receiver will know exactly how many bytes to read.char *recv_buf
, and similarly forrecv_buf1
. You don't allocate any storage for any of the two pointers, so they aren't pointing to anywhere useful. Then, yourrecv
call is:recv(msgsock, recv_buf, sizeof(recv_buf), 0);
This also has problems. The first is the one mentioned above: you don't have storage forrecv_buf
. The second is that after you do allocate storage forrecv_buf
, you are taking the size of a char pointer instead of the length of the bufferrecv
points to. One easy way to solve both the issues would be to declarerecv_buf
as:char recv_buf[SIZE];
and then usesizeof recv_buf
in therecv()
call.I haven't looked at the rest of your code. You probably need a good C and network programming introduction.
我认为您将 C 字符串的空终止与套接字上发送的数据包的结尾混淆了。数据包没有“终止”,它只是一串字节。零是完全合法的,并且您明确地传递(和接收)长度。您当然不需要使用带外设施来接收多个数据包。您能更具体地说明您要问的内容吗?
I think you're confusing the null-termination of a C string with the end of a packet sent on a socket. There is no "termination" of a packet, it's just a string of bytes. Zeros are completely legal, and you pass (and receive) the length explicitly. You certainly don't need to use the out-of-band facilities to receive multiple packets. Can you be more specific about what you're asking?