C语言 使用“C”在套接字编程中发送数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6798967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending Data in socket programming using "C"
提问by user537670
I had earlier posted a question, regarding same, but over here i want guidance for my code. Using the tips from people I have tried to create for sending a packet. My max packet structure alongwith header and payload is of 16 bytes.Kindly if possible glance through the sending and receiving code and suggest where i am going wrong. Basically my client keeps sending data to server,it just doesn't end and server doesn't show results.
我早些时候发布了一个关于相同的问题,但在这里我需要有关我的代码的指导。使用我尝试创建的人的提示来发送数据包。我的最大数据包结构以及标头和有效载荷为 16 字节。如果可能,请浏览发送和接收代码并建议我哪里出错了。基本上我的客户端不断向服务器发送数据,它只是没有结束,服务器也没有显示结果。
Client:
客户:
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
struct packet
{
long int srcID;
long int destID;
long int pver;
long int profiles;
char length;
long int data;
};
if (argc < 3) {
fprintf(stderr,"usage: %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]); //Convert ASCII to integer
sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in opening socket\n");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR DETECTED !!!, no such server found \n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address
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);
printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno);
if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR in connection");
printf("SUCCESS !!! Connection established \n");
char buffer[128];
struct packet *pkt = (struct packet *) buffer;
char *payload = buffer + sizeof(struct packet);
long int packet_size;
printf("Started Creating packet\n");
pkt->srcID = 0x01;
pkt->destID = 0x02;
pkt->pver = 0x01;
pkt->profiles = 0x01;
pkt->length = 128;
pkt->data = 1; 2; 3; 4; 5; 6; 7; 8;
if (send(sockfd,pkt,sizeof(packet_size),0) <0)
printf ("error\n");
else
printf ("packet send done");
return 0;
}
Server:
服务器:
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
char wish;
long int SrcID;
long int DestID;
long int Pver;
long int Profiles;
long int Data;
char Length;
char bytes_to_receive;
char received_bytes;
struct packet
{
long int srcID;
long int destID;
long int pver;
long int profiles;
char length;
long int data;
};
if (argc < 2) {
fprintf(stderr,"usage: %s port_number1",argv[0]);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR DETECTED !!! Problem in 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 = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR DETECTED !!! There was a problem in binding");
listen(sockfd, 10);
clilen = sizeof(cli_addr);
printf("Server listening on port number %d...\n", serv_addr.sin_port);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR DETECTED !!! the connection request was not accepted");
char buffer[128];
struct packet *pkt = (struct packet *) buffer;
char *payload = buffer + sizeof(struct packet);
long int packet_size;
bytes_to_receive = sizeof(pkt);
received_bytes = 0;
if (recv(newsockfd, pkt, sizeof(pkt), 0) < 0)
error("ERROR DETECTED !!! There was a problem in reading the data");
else
{
do {
received_bytes += (buffer + received_bytes, bytes_to_receive - received_bytes);
} while (received_bytes != bytes_to_receive);
SrcID = pkt->srcID;
DestID = pkt->destID;
Pver = pkt->pver ;
Profiles = pkt->profiles;
Length = pkt->length;
Data = pkt->data;
printf("Data Received from Client_1 are :\n");
printf("Source ID: %l\n", SrcID);
printf("Destination ID: %l\n", DestID);
printf("profile Version: %l\n", Pver);
printf("No of Profiles: %l\n", Profiles);
printf("Length: %l\n", Length);
printf("data : %l\n", Data);
}
if (close(newsockfd) == -1) {
error("Error closing connection with client 1");
}
printf("Connection with client 1 has been closed\n");
return 0;
}
The server is not showing any o/p. Client says it has send the packet. While compiling the server code i see four warnings saying unknown conversion type characters 0xa in format for all the printf statements in server code. I guess I am going wrong somewhere in the server code side, but I am not able to follow the "serialization". Please update me with your inputs, it would be of great help.
服务器没有显示任何 o/p。客户端说它已发送数据包。在编译服务器代码时,我看到四个警告说服务器代码中所有 printf 语句的格式为未知转换类型字符 0xa。我想我在服务器代码端的某个地方出错了,但我无法遵循“序列化”。请用您的输入更新我,这将有很大帮助。
采纳答案by Kevin M
The problem with the client continually sending is because you simply have it in a loop. With indentation fixed, it becomes clear what has happened:
客户端不断发送的问题是因为你只是让它处于循环中。缩进固定后,发生的事情就很清楚了:
while (1)
{
if (send(sockfd,pkt,sizeof(packet_size),0) <0)
printf ("error\n");
else
printf ("packet send done");
}
回答by Zuljin
Here is couple of issues that I found:
这是我发现的几个问题:
- Your client keep sending packages because it is in infinite while loop.
- You passed wrong len parameter of recv function. Right now you pass sizeof(packet_size) which is equal to sizeof(long int) (4 bytes on 32 bit OS), but probably your intension was to use sizeof(packet) (16 bytes).
You don't check how many bytes were truly read by recv function. With TCP you don't have guaranties that you read all 16 bytes of struct packet. So from time to time you could read less bytes and your packet will be incomplete. Here is an example in some pseudo code how you should receive whole packet:
bytes_to_receive = sizeof(packet) received_bytes = 0; do { received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes) } while (received_bytes != bytes_to_receive)Your struct
packetin client and server is different. In one you usechar length;in secondlong int length;I think also this kind of assignments in server make no sense
pkt->srcID = SrcID;and should be something like thisSrcID = pkt->srcID;
- 您的客户不断发送包裹,因为它处于无限循环中。
- 您传递了错误的 recv 函数的 len 参数。现在您传递的 sizeof(packet_size) 等于 sizeof(long int)(32 位操作系统上的 4 个字节),但您的意图可能是使用 sizeof(packet)(16 个字节)。
您不会检查 recv 函数真正读取了多少字节。使用 TCP,您无法保证读取 struct 数据包的所有 16 个字节。因此,有时您可能会读取较少的字节,并且您的数据包将不完整。这是一些伪代码中的示例,您应该如何接收整个数据包:
bytes_to_receive = sizeof(packet) received_bytes = 0; do { received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes) } while (received_bytes != bytes_to_receive)您
packet在客户端和服务器中的结构是不同的。在一个你char length;在第二个使用long int length;我认为服务器中的这种分配也没有意义
pkt->srcID = SrcID;,应该是这样的SrcID = pkt->srcID;
回答by ddd
addr_size = sizeof serverAddr;
connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);
连接(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

