我编写的程序像TCP客户端的电话运营商一样工作。 TCP客户端连接到服务器,然后为服务器提供通道名称。 如果另一个TCP客户端连接到服务器并提供相同的通道名称,则服务器将两个TCP客户端连接在一起,允许它们相互通信而不会受到干扰。
当我在Mac上编译它时,它工作正常,但当我把它放在数字海洋液滴上时,我在编译期间遇到此错误。我使用netbeans生成了makefile。
这是StreamSwitch.h
#ifndef STREAMSWITCH_H
#define STREAMSWITCH_H
#include <string>
#include <sstream>
#include <iostream>
#include <list>
using namespace std;
struct Comparator{
int length;
uint8_t *pointer;
};
class DiscriptorNode{
public:
int FileDiscriptor;
uint8_t ChannelName[1000];
bool operator == (const DiscriptorNode& s) const { return (this->FileDiscriptor) == (s.FileDiscriptor); }
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
bool operator != (const DiscriptorNode& s) const { return !operator==(s); }
};
class StreamConnection{
public:
int FileDiscriptors[2];
bool operator == (const StreamConnection& s) const { return this->FileDiscriptors == s.FileDiscriptors; }
bool operator != (const StreamConnection& s) const { return !operator==(s); }
};
class StreamSwitch{
list <DiscriptorNode> Unconnected;
list <StreamConnection> Connected;
int ServerFileDiscriptor;
int PortNumber;
string ErrorMessage;
public:
StreamSwitch(int portNumber);
void HandleCommunication();
bool Begin();
string GetError();
};
#endif /* STREAMSWITCH_H */
这是StreamSwitch.cpp
#include "StreamSwitch.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstdlib>
#include <iostream>
#include <sys/select.h>
#include <unistd.h>
void remove(list<DiscriptorNode> List, list<DiscriptorNode>:: iterator &Iterator){
list<DiscriptorNode> ::iterator temp=Iterator;
Iterator++;
List.erase(temp);
}
void remove(list<StreamConnection> List, list<StreamConnection>:: iterator &Iterator){
list<StreamConnection> ::iterator temp=Iterator;
Iterator++;
List.erase(temp);
}
StreamSwitch::StreamSwitch(int portNumber) {
this->PortNumber=portNumber;
}
bool StreamSwitch::Begin(){
int ReUseSocket=1;
struct sockaddr_in ServerAddress;
this->ServerFileDiscriptor=socket(AF_INET, SOCK_STREAM, 0);
bzero((char *) &ServerAddress, sizeof (ServerAddress));
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons(PortNumber);
ServerAddress.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(this->ServerFileDiscriptor, SOL_SOCKET, SO_REUSEADDR, &ReUseSocket, sizeof (ReUseSocket)) == 1) {
return 1;
}
if (bind(this->ServerFileDiscriptor, (struct sockaddr *) &ServerAddress, sizeof (ServerAddress)) < 0) {
std::stringstream ss;
ss<<"Could not bind, port "<<this->PortNumber<<" is being used";
this->ErrorMessage=ss.str();
return false;
}
listen(this->ServerFileDiscriptor, 1024);
return true;
}
uint8_t InputDataBuffer[1000];
void StreamSwitch::HandleCommunication(){
int maximumFd=0;
struct timeval Timer_Variable;
list<DiscriptorNode> ::iterator DiscIterator;
list<StreamConnection> ::iterator ConnectionIterator;
fd_set ReadFileDiscriptors, ExceptFileDiscriptors, WriteFileDiscriptors;
Timer_Variable.tv_sec = 0;
Timer_Variable.tv_usec = 100;
FD_ZERO(&ReadFileDiscriptors);
FD_ZERO(&WriteFileDiscriptors);
FD_ZERO(&ExceptFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &ReadFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &WriteFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &ExceptFileDiscriptors);
if (maximumFd<this->ServerFileDiscriptor) {
maximumFd = this->ServerFileDiscriptor;
}
for (DiscIterator = this->Unconnected.begin(); DiscIterator != this->Unconnected.end(); DiscIterator++) {
FD_SET((*DiscIterator).FileDiscriptor, &ReadFileDiscriptors);
FD_SET((*DiscIterator).FileDiscriptor, &WriteFileDiscriptors);
FD_SET((*DiscIterator).FileDiscriptor, &ExceptFileDiscriptors);
if (maximumFd < (*DiscIterator).FileDiscriptor) {
maximumFd = (*DiscIterator).FileDiscriptor;
}
}
for (ConnectionIterator = this->Connected.begin(); ConnectionIterator != this->Connected.end(); ConnectionIterator++) {
for (int i = 0; i < 2; i++) {
FD_SET((*ConnectionIterator).FileDiscriptors[i], &ReadFileDiscriptors);
FD_SET((*ConnectionIterator).FileDiscriptors[i], &WriteFileDiscriptors);
FD_SET((*ConnectionIterator).FileDiscriptors[i], &ExceptFileDiscriptors);
if (maximumFd < (*ConnectionIterator).FileDiscriptors[i]) {
maximumFd = (*ConnectionIterator).FileDiscriptors[i];
}
}
}
maximumFd++;
select(maximumFd,&ReadFileDiscriptors,&WriteFileDiscriptors,&ExceptFileDiscriptors,&Timer_Variable);
if(FD_ISSET(this->ServerFileDiscriptor,&ReadFileDiscriptors)){
struct sockaddr_in ClientAddress;
DiscriptorNode node;
socklen_t clientLength=sizeof(ClientAddress);
node.FileDiscriptor=accept(this->ServerFileDiscriptor, (struct sockaddr *) &ClientAddress, &clientLength);
cout<<"Got a new connection"<<endl;
bzero(node.ChannelName,sizeof(node.ChannelName));
this->Unconnected.push_back(node);
}
for (DiscIterator = this->Unconnected.begin(); DiscIterator != this->Unconnected.end(); DiscIterator++) {
if(FD_ISSET((*DiscIterator).FileDiscriptor,&ExceptFileDiscriptors)){
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
int errorsoc = 0;
socklen_t len = sizeof (errorsoc);
int retval = getsockopt((*DiscIterator).FileDiscriptor
, SOL_SOCKET
, SO_ERROR
, &errorsoc
, &len);
if ((retval != 0) || (errorsoc != 0)) {
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
if(FD_ISSET((*DiscIterator).FileDiscriptor,&ReadFileDiscriptors)){
int TransferCount;
bzero(InputDataBuffer,sizeof(InputDataBuffer));
TransferCount=read((*DiscIterator).FileDiscriptor, InputDataBuffer, sizeof(InputDataBuffer));
if (TransferCount < 1) {
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
Comparator s;
cout<<"Got this data "<<InputDataBuffer<<endl;
s.pointer=InputDataBuffer;
s.length=TransferCount;
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
if(matching==this->Unconnected.end()){
cout<<"Did not find matching"<<endl;
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
continue;
}
cout<<"Matched "<<InputDataBuffer<<endl;
StreamConnection connect;
connect.FileDiscriptors[0]=(*matching).FileDiscriptor;
connect.FileDiscriptors[1]=(*DiscIterator).FileDiscriptor;
remove(this->Unconnected,matching);
remove(this->Unconnected,DiscIterator);
this->Connected.push_back(connect);
}
}
for (ConnectionIterator = this->Connected.begin(); ConnectionIterator != this->Connected.end(); ConnectionIterator++) {
for (int i = 0; i < 2; i++) {
if (FD_ISSET((*ConnectionIterator).FileDiscriptors[i], &ExceptFileDiscriptors)) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1-i]);
remove(this->Connected,ConnectionIterator);
break;
}
int errorsoc = 0;
socklen_t len = sizeof (errorsoc);
int retval = getsockopt((*ConnectionIterator).FileDiscriptors[i]
, SOL_SOCKET
, SO_ERROR
, &errorsoc
, &len);
if ((retval != 0) || (errorsoc != 0)) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1-i]);
remove(this->Connected,ConnectionIterator);
break;
}
if (FD_ISSET((*ConnectionIterator).FileDiscriptors[i], &ReadFileDiscriptors)) {
int TransferCount;
bzero(InputDataBuffer, sizeof (InputDataBuffer));
TransferCount = read((*ConnectionIterator).FileDiscriptors[i], InputDataBuffer, sizeof (InputDataBuffer));
if (TransferCount < 1) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1 - i]);
remove(this->Connected,ConnectionIterator);
break;
}
// cout<<"This is the data received "<<InputDataBuffer<<endl;
write((*ConnectionIterator).FileDiscriptors[1-i],InputDataBuffer,TransferCount);
}
}
}
}
string StreamSwitch::GetError(){
return this->ErrorMessage;
}
这是我的主要
#include <list>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include "StreamSwitch.h"
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
StreamSwitch switcher(1234);
bool success=switcher.Begin();
if(!success){
cout<<switcher.GetError();
return 0;
}
while(1){
switcher.HandleCommunication();
usleep(1000);
}
return 0;
}
我检查了我的make文件并确认它运行以下命令进行编译
g++ -c -g -MMD -MP -MF "build/Debug/GNU-MacOSX/StreamSwitch.o.d" -o build/Debug/GNU-MacOSX/StreamSwitch.o StreamSwitch.cpp
mkdir -p dist/Debug/GNU-MacOSX
g++ -o dist/Debug/GNU-MacOSX/streamswitch build/Debug/GNU-MacOSX/StreamSwitch.o build/Debug/GNU-MacOSX/main.o
这是我在数字海洋水滴上的错误
g++ -c -g -MMD -MP -MF "build/Debug/GNU-MacOSX/StreamSwitch.o.d" -o build/Debug/GNU-MacOSX/StreamSwitch.o StreamSwitch.cpp
In file included from StreamSwitch.cpp:7:0:
StreamSwitch.h:23:5: error: ‘uint8_t’ does not name a type
uint8_t *pointer;
^
StreamSwitch.h:28:5: error: ‘uint8_t’ does not name a type
uint8_t ChannelName[1000];
^
StreamSwitch.h: In member function ‘bool DiscriptorNode::operator==(const Comparator&) const’:
StreamSwitch.h:30:68: error: ‘const struct Comparator’ has no member named ‘pointer’
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.h:30:82: error: ‘const class DiscriptorNode’ has no member named ‘ChannelName’
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.h:30:102: error: ‘memcmp’ was not declared in this scope
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.cpp: In member function ‘bool StreamSwitch::Begin()’:
StreamSwitch.cpp:34:58: error: ‘bzero’ was not declared in this scope
bzero((char *) &ServerAddress, sizeof (ServerAddress));
^
StreamSwitch.cpp: In member function ‘void StreamSwitch::HandleCommunication()’:
StreamSwitch.cpp:95:20: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:95:44: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:95:56: error: ‘bzero’ was not declared in this scope
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:119:58: error: ‘bzero’ was not declared in this scope
bzero(InputDataBuffer,sizeof(InputDataBuffer));
^
StreamSwitch.cpp:128:15: error: ‘struct Comparator’ has no member named ‘pointer’
s.pointer=InputDataBuffer;
^
StreamSwitch.cpp:130:114: error: no matching function for call to ‘find(std::list<DiscriptorNode>::iterator, std::list<DiscriptorNode>::iterator, Comparator&)’
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
^
StreamSwitch.cpp:130:114: note: candidate is:
In file included from /usr/include/c++/4.8/bits/locale_facets.h:48:0,
from /usr/include/c++/4.8/bits/basic_ios.h:37,
from /usr/include/c++/4.8/ios:44,
from /usr/include/c++/4.8/istream:38,
from /usr/include/c++/4.8/sstream:38,
from StreamSwitch.h:17,
from StreamSwitch.cpp:7:
/usr/include/c++/4.8/bits/streambuf_iterator.h:369:5: note: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT> >::__type std::find(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, const _CharT2&)
find(istreambuf_iterator<_CharT> __first,
^
/usr/include/c++/4.8/bits/streambuf_iterator.h:369:5: note: template argument deduction/substitution failed:
StreamSwitch.cpp:130:114: note: ‘std::_List_iterator<DiscriptorNode>’ is not derived from ‘std::istreambuf_iterator<_CharT>’
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
^
StreamSwitch.cpp:133:40: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
^
StreamSwitch.cpp:133:81: error: ‘memcpy’ was not declared in this scope
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
^
StreamSwitch.cpp:168:64: error: ‘bzero’ was not declared in this scope
bzero(InputDataBuffer, sizeof (InputDataBuffer));
^
请帮我弄清楚如何为ubuntu解决这个问题,如果有人能解释我将来如何避免这个问题,我会很高兴。
我通过在StreamSwitch.h中添加以下标题来修复此问题
#include <string.h>
#include <algorithm>
#include <inttypes.h>
并从StreamSwitch.h中删除以下内容
#include <string>
我仍然不知道发生了什么,或者为什么代码在Mac上编译而不是在数字Ocean Droplet上编译,或者我将来如何能够避免这个问题。
答案 0 :(得分:0)
固定宽度标准类型出现在C99和C ++ 11中,见
http://en.cppreference.com/w/c/types/integer
http://en.cppreference.com/w/cpp/types/integer
它们在“”和“”中声明/定义。
因此,独立解决问题平台的两个步骤是
1)#include <stdint.h>
或#include <stdint>
2)确保按C99或C ++ 11标准编译,
可能需要使用特殊的comandline参数,
在你的编译器的文档/帮助中查找
注意: 我扩展了最初的C答案以涵盖两者。同时删除了C标签。我认为保留C上的信息是值得/无害的。