我正在尝试使用C ++中的UDP编写双向聊天程序。这是我的代码:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <string>
enum { RECV_PORT = 5023, MSGSIZE = 1024 };
socklen_t addr_len = sizeof(sockaddr) ;
int receiver( int socket_fd )
{
sockaddr_in my_addr ;
std::memset( &my_addr, 0, sizeof(my_addr) ) ;
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons( RECV_PORT ) ;
my_addr.sin_addr.s_addr = INADDR_ANY ;
if ( bind( socket_fd, (sockaddr*)&my_addr, addr_len ) != 0 )
return 2 ;
sockaddr_in client_addr ;
while( true )
{
char recv_data[MSGSIZE+1] ;
int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0,
(sockaddr*)&client_addr, &addr_len ) ;
if( bytes_recd == -1 ) break ;
recv_data[bytes_recd] = '\0' ;
std::cout << "Message from " << inet_ntoa(client_addr.sin_addr)
<< ':' << ntohs(client_addr.sin_port) << " - "
<< recv_data << std::endl ;
std::string send_str ;
while( std::getline( std::cin, send_str ) )
{
send_str.resize(MSGSIZE) ;
sendto( socket_fd, send_str.c_str(), MSGSIZE, 0,
(sockaddr*)&client_addr, addr_len ) ;
}
return 0 ;
}
}
int sender( int socket_fd )
{
std::cout << "IP Address of server: " ;
std::string address ;
std::cin >> address >> std::ws ;
sockaddr_in member_addr ;
std::memset( &member_addr, 0, sizeof(member_addr) ) ;
member_addr.sin_family = AF_INET ;
member_addr.sin_port = htons( RECV_PORT ) ;
member_addr.sin_addr.s_addr =
*(in_addr_t*)(gethostbyname( address.c_str() )->h_addr) ;
std::string send_str ;
while( std::getline( std::cin, send_str ) )
{
send_str.resize(MSGSIZE) ;
sendto( socket_fd, send_str.c_str(), MSGSIZE, 0,
(sockaddr*)&member_addr, addr_len ) ;
}
while( true )
{
sockaddr_in server_addr ;
char recv_data[MSGSIZE+1] ;
int bytes_recd = recvfrom( socket_fd, recv_data, MSGSIZE, 0,
(sockaddr*)&server_addr, &addr_len ) ;
if( bytes_recd == -1 ) break ;
recv_data[bytes_recd] = '\0' ;
std::cout << "Message from " << inet_ntoa(server_addr.sin_addr)
<< ':' << ntohs(server_addr.sin_port) << " - "
<< recv_data << std::endl ;
}
return 0 ;
}
int main()
{
int socket_fd = socket( AF_INET, SOCK_DGRAM, 0 ) ;
if( socket_fd == -1 ) return 1 ;
return fork() == 0 ? receiver( socket_fd ) : sender( socket_fd ) ;
}
当我在客户端窗口上键入消息时,消息显示在服务器窗口上,但是当我在服务器窗口上键入消息时,消息显示的不是服务器窗口而不是客户端窗口。为什么会这样?有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
请勿使用fork(2)
对此进行编码 - 您的父进程和子进程 share
使用相同的套接字(子进程继承父进程的文件描述符)。这肯定会搞砸一切。
只需引入一个命令行参数,告诉main()
在发送方或接收方中运行哪种模式,并在不同的终端窗口(最终在不同的计算机上)运行它们。
答案 1 :(得分:0)
当我在客户端窗口上输入消息时..
您有单独的终端会话?您正在分叉并绑定到其中一个进程中的端口(同样SD也是如此)。因此,从单独的窗口运行另一个程序实例,它不会有绑定错误吗?但是,您的receiver
逻辑会运行。您应该基于命令行参数来决定程序实例是客户端还是服务器。
while(true)
循环中的发件人中,用于从用户获取输入和发送。而在其他接收套接字上的数据。显然,一个注定只接收数据而另一个注定要发送数据。它不是双向的。