C++ 发送和接收 TCP/IP 结构
C++ Sending and Receiving TCP/IP structure
这是我的客户:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
using namespace std;
typedef struct TEMPIO
{
unsigned int id;
unsigned short messageSender;
unsigned short length;
unsigned int secs;
unsigned int usecs;
unsigned short videoId;
unsigned short outChannel;
}TEMPIO_msg;
int client();
int server();
void error();
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(){
int sockfd, portno, n;
char * address;
struct sockaddr_in serv_addr;
struct hostent *server;
TEMPIO_msg message;
struct timeval time;
portno=2015;//TBD take portno
address="127.0.0.1";//TBD take address
message.id=htonl(1694367746);
message.messageSender=htons(100);
message.length=htons(20);
gettimeofday(&time,NULL);
message.secs=htonl(time.tv_sec);
message.usecs=htonl(time.tv_usec);
message.videoId=htons(44);
message.outChannel=htons(38);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
error("ERROR opening socket");
exit(0);
}
server = gethostbyname(address);
if (server == NULL) {
fprintf(stderr,"ERROR, no such hostn");
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");
exit(0);
}
while(true){
if (sendto(sockfd,&message,sizeof(TEMPIO_msg),MSG_EOR,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
perror("sendto");
exit(1);
}else{
printf("CLI: sent something...n");
}
sleep(3);
}
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 <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
using namespace std;
typedef struct TEMPIO
{
unsigned int id;
unsigned short messageSender;
unsigned short length;
unsigned int secs;
unsigned int usecs;
unsigned short videoId;
unsigned short outChannel;
}TEMPIO_msg;
int client();
int server();
void error();
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(){
int sockfd, newsockfd, portno;
char * address;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
TEMPIO_msg message;
struct timeval time;
address="127.0.0.1";
portno = 2015; // TBD
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
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);
printf("SRV: started! n");
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) error("ERROR on accept");
printf("SRV: client connected! n");
printf("SRV: Listening... ");
if (recvfrom(sockfd,&message,sizeof(TEMPIO_msg),MSG_PEEK,(struct sockaddr *) &cli_addr, &clilen) > 0)
{
printf("SRV catched something!n");
}
close(newsockfd);
close(sockfd);
return 0;
}
如您所见,我正在使用以下函数来发送/接收数据结构:
ssize_t recvfrom(int socket, void *restrict buffer, size_t length,
int flags, struct sockaddr *restrict address,
socklen_t *restrict address_len);
ssize_t sendto(int socket, const void *message, size_t length,
int flags, const struct sockaddr *dest_addr,
socklen_t dest_len);
我的代码已正确编译,但无法正常工作。这太奇怪了,因为我在客户端之后启动了服务器,服务器似乎卡在了这一点:
$ ./srv SRV: started!
SRV: client connected!
客户端正在正确发送数据包,并且服务器仅在客户端发送 4 次后才继续执行
$ ./cli
CLI: sent something...
CLI: sent something...
CLI: sent something...
CLI: sent something...
这很奇怪,因为如您所见,服务器似乎卡在两个 printf(客户端连接和侦听(之间:
./srv SRV: started!
SRV: client connected!
SRV: Listening...
你能抓住问题所在吗?
服务器
中的recvfrom
调用正在尝试从侦听套接字sockfd
读取。 相反,您应该从newsockfd
读取,这是连接的套接字。
此外,您应该将 recvfrom
的返回值复制到变量中。 您将首先检查它是否为 -1,在这种情况下,您将处理错误。如果没有,您将检查以确保您读取了预期的字节数。
关于recvfrom
:它和sendto
都应该分别替换为recv
和send
,因为你正在处理TCP套接字;所以端点是已知的。
相关文章:
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 用于C++的 TCP/IP 解析器和响应器
- 是否有一种标准化的方法通过TCP/IP网络发送JPG图像
- 使用 xcvdata 删除标准 TCP IP 端口不起作用
- TCP/IP - 以 C/C++ 格式发送十六进制数据包以控制中继板
- TCP/IP 客户端是否可以连接到无法访问的 IP
- 如何通过TCP/IP Winsock发送双型数据
- 如何在 TCP/IP 服务器中中断 accept()?
- 我们如何从BOOST :: ASIO :: TCP :: ip :: read_some呼叫中顺序接收多个数据
- 通过C 中的TCP/IP协议发送.TXT文件
- 如何避免通过TCP/IP SSH隧道在数据传输中重复读取数据
- TCP/IP文件传输C
- 委托使用 boost asio TCP/IP 套接字
- 处理插座Boost ASIO TCP IP -C 套接字编程
- 网络传输时间从TCP/IP堆栈
- POSIX套接字与Web套接字与Windows TCP/IP套接字
- C++套接字编程TCP/IP套接字缓冲区的最大大小
- C++客户端到Java服务器(TCP/IP)
- Windows TCP IP 套接字编程
- Winsock2 tcp/ip-一些数据包被忽略,可能是由于前一个数据包的null终止符