У меня есть сервер и клиент, и я пытаюсь отправить сообщение от клиента на сервер в виде строки. Я успешно сделать это один раз, но при попытке отправить другую строку, я получаю ошибку: client: connect error :Transport endpoint is already connected
Клиент-сервер отправляет строковое сообщение C++
----- Компиляция -----
g++ server.cpp -std=c++11 -o server.x -lpthread
g++ client.cpp -std=c++11 -o client.x
----- Как выполнить -----
./server.x
./client.x <IP Address>
После выполнения обоих файлов, следующие опции появятся:
---------- ---------- параметры
сервер - отправить команду на сервер выход - программы
Если вы наберете «сервер» на выход, следующие варианты будут:
----- сервера Опции команды: -----
м - отправить сообщение на сервер
server.cpp
int main() {
int sockid, newsd;
struct sockaddr_in my_addr, client_addr;
socklen_t clilen = sizeof(client_addr);
thread cmd;
cout << "Server creating socket.\n";
if((sockid = socket(AF_INET,SOCK_STREAM,0)) < 0) {
cout << "Socket Error.\n";
exit(0);
}
cout << "Server binding my local socket.\n";
bzero((char *) &my_addr,sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MY_PORT_ID);
my_addr.sin_addr.s_addr = htons(INADDR_ANY);
if(bind(sockid ,(struct sockaddr *) &my_addr,sizeof(my_addr)) < 0) {
cout << "Bind error.\n";
exit(0);
}
cout << "Server starting listen.\n";
if(listen(sockid,5) < 0) {
cout << "Listen error.\n";
exit(0);
}
cout << "Server running...listening for connections.\n";
for(; ;) {
cout << "Server starting accept.\n";
cout << "newd: " << newsd << endl;
cout << "sockid: " << sockid << endl;
cout << "client_addr: " << &client_addr << endl;
cout << "clilen: " << clilen << endl;
if ((newsd = accept(sockid ,(struct sockaddr *) &client_addr, &clilen)) < 0) {
perror("Failed to accept.");
exit(0);
}
cout << "newsd: " << newsd << endl;
cout << "Server return from accept, socket for this ftp: "<< newsd << endl;
// close(sockid); /* child shouldn't do an accept */
thread cmd (receiveCommand, newsd);
//cmd.detach();
//cmd.join();
// close (newsd);
// exit(0); /* child all done with work */
}
// cmd.join();
/* Parent continues below here */
close(newsd); /* parent all done with client, only child */
close(sockid);
return 0;
}
void receiveCommand(int newsd)
{
string cmd;
int msg_ok,fail,req,tmp;
char command[MAXLINE], commandSize = 0;
req = 0;
if((readn(newsd,(char *)&req,sizeof(req))) < 0) {
perror("Read error");
exit(0);
}
req = ntohs(req);
cout << "Client request code is: " << req << endl;
if (req!=REQUESTCOMMAND) {
cout << "Unsupported operation. goodbye\n";
/* reply to client: command not OK (code: 150) */
msg_ok = COMMANDNOTSUPPORTED;
msg_ok = htons(msg_ok);
if((writen(newsd,(char *)&msg_ok,sizeof(msg_ok))) < 0) {
perror("Write error.");
exit(0);
}
exit(0);
}
/* reply to client: command OK (code: 160) */
msg_ok = COMMANDSUPPORTED;
msg_ok = htons(msg_ok);
if(writen(newsd,(char *)&msg_ok,sizeof(msg_ok)) < 0) {
perror("Write error.");
exit(0);
}
fail = COMMANDOK;
if((commandSize = read(newsd,command,MAXLINE)) < 0) {
perror("Command read error.");
fail = BADCOMMAND ;
}
command[commandSize] = '\0';
tmp = htons(fail);
if((writen(newsd,(char *)&tmp,sizeof(tmp))) < 0) {
perror("Write error");
exit(0);
}
if(fail == BADCOMMAND) {
cout << "Server cant do command.\n";
close(newsd);
exit(0);
}
cout << "Command is: " << command << endl;
if(command == "gbye"){
cout << endl;
cout << "Client requested server to shutdown...\n";
cout << "Goodbye.\n";
exit(0);
}
else{
cout << "Command TRANSFER COMPLETE on socket " << newsd << endl;
}
close(newsd);
}
/*
To take care of the possibility of buffer limmits in the kernel for the
socket being reached (which may cause read or write to return fewer characters
than requested), we use the following two functions */
int readn(int sd,char *ptr,int size)
{
int no_left,no_read;
no_left = size;
while (no_left > 0) {
no_read = read(sd,ptr,no_left);
if(no_read <0) return(no_read);
if (no_read == 0) break;
no_left -= no_read;
ptr += no_read;
}
return(size - no_left);
}
int writen(int sd,char *ptr,int size)
{ int no_left,no_written;
no_left = size;
while (no_left > 0) {
no_written = write(sd,ptr,no_left);
if(no_written <=0) return(no_written);
no_left -= no_written;
ptr += no_written;
}
return(size - no_left);
}
client.cpp
int main(int argc,char *argv[])
{
int sockid, newsd, portNum, clientportNum, serverportNum;
struct sockaddr_in my_addr, server_addr;
if(argc != 2) {
cout << "Error: Usage : IP-dotted-notation \n", argv[0];
exit(0);
}
if((sockid = socket(AF_INET,SOCK_STREAM,0)) < 0) {
cout << "Client Socket Error.\n";
exit(0);
}
clientportNum = 8000;
serverportNum = 8001;
cout << "Client Binding My Local Socket\n";
bzero((char *) &my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons(clientportNum);
if(bind(sockid ,(struct sockaddr *) &my_addr,sizeof(my_addr)) < 0){
cout << "Client Bind Error.\n";
exit(0);
}
cout << "Client Starting Connect\n";
bzero((char *) &server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(serverportNum);
while(1){
string cmd_option;
cout << endl;
cout << "---------- Options ----------\n";
cout << "server - send a command to the server\n";
cout << "exit - exit program\n";
cout << endl;
cout << "~: ";
getline(cin, cmd_option);
if(cmd_option == "server"){
// *****Error Here*****
if(connect(sockid ,(struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
//cout << "Client Connect Error.\n";
printf("client: connect error :%s\n", strerror(errno));
exit(0);
}
giveServerCommand(sockid);
}
else if(cmd_option == "exit"){
cout << endl;
cout << "Exiting program...\n";
cout << "Goodbye.\n";
exit(0);
}
else{
cout << "Invalid Command.\n";
}
}
}
void giveServerCommand(int sockid)
{
string user_input;
// User Interface
cout << "\n-----Server Command Options:-----\n";
cout << "m - send message to server\n";
cout << "\n";
cout << "~: ";
getline(cin, user_input);
if (user_input == "m"){
string buffer;
cout << "\nType a command to the server: ";
getline(cin, buffer);
cout << "You typed: " << buffer << endl;
int getcommand,msg,msg_2,len;
len = buffer.size();
getcommand = htons(REQUESTCOMMAND);
cout << "Client sending command request to server.\n";
int n = 0;
if(n = (writen(sockid,(char *)&getcommand,sizeof(getcommand))) < 0) {
cout << "Client write error: " << n << endl;
exit(0);
}
/* want for go-ahead from server */
cout << "command: " << getcommand << endl;
cout << "sockid: " << sockid << endl;
cout << "msg: " << &msg << endl;
cout << "msg size: " << sizeof(msg) << endl;
msg = 0;
if((readn(sockid,(char *)&msg,sizeof(msg)))< 0) {
cout << "Client read error.\n";
exit(0);
}
cout << "msg: " << msg << endl;
msg = ntohs(msg);
cout << "msg after ntohs: " << msg << endl;
if (msg==COMMANDNOTSUPPORTED) {
cout << "Server refused command. Goodbye...\n";
cout << endl;
exit(0);
}
else
cout << "Server replied, command supported.\n";
/* send command to server */
cout << "Client sending command.\n";
cout << "sockid: " << sockid << endl;
cout << "buffer: " << buffer.c_str() << endl;
cout << "len: " << len << endl;
if ((writen(sockid, (char *) buffer.c_str(),len)) < 0) {
cout << "Client write error.\n";
exit(0);
}
/* see if server replied that command is OK */
cout << "sockid: " << sockid << endl;
cout << "msg2: " << &msg_2 << endl;
cout << "msg2 size: " << sizeof(msg_2) << endl;
msg_2 = 0;
if (readn(sockid, (char *)&msg_2, sizeof(msg_2)) < 0) {
cout << "Client read error: %s\n", strerror(errno);
exit(0);
}
cout << "msg2 before ntohs: " << msg_2 << endl;
msg_2 = ntohs(msg_2);
cout << "msg2 after ntohs: " << msg_2 << endl;
if (msg_2 == BADCOMMAND) {
cout << "Server reported bad command. Goodbye...\n";
exit(0);
}
else
cout << "Server replied, Command OK.\n";
/*Command transfer ends. client terminates after closing all its sockets*/
cout << "COMMAND TRANSFER COMPLETE\n";
}
else{
cout << "\nInvalid Option.\n";
}
}
int readn(int sd, char *ptr, int size)
{
int no_left,no_read;
cout << "-----Within readn function------" << endl;
cout << "sd: " << sd << endl;
cout << "char ptr: " << &ptr << endl;
cout << "size: " << size << endl;
no_left = size;
while (no_left > 0) {
no_read = read(sd,ptr,no_left);
cout << "no_read: " << no_read << endl;
if(no_read <0) return(no_read);
if (no_read == 0) break;
no_left -= no_read;
ptr += no_read;
}
cout << "size - no_left: " << size - no_left << endl;
cout << "--------------------------------" << endl;
return(size - no_left);
}
int writen(int sd,char *ptr,int size)
{
/*
cout << "-----Within writen function------" << endl;
cout << "sd: " << sd << endl;
cout << "char ptr: " << &ptr << endl;
cout << "size: " << size << endl;
*/
int no_left,no_written;
no_left = size;
while (no_left > 0) {
no_written = write(sd,ptr,no_left);
//cout << "no_written: " << no_written << endl;
if(no_written <=0) return(no_written);
no_left -= no_written;
ptr += no_written;
}
/*
cout << "size - no_left: " << size - no_left << endl;
cout << "--------------------------------" << endl;
*/
return(size - no_left);
}
Ошибка: client: connect error :Transport endpoint is already connected
Вы используете несколько клиентов или серверов одновременно на одном компьютере? –
Только один клиент и один сервер на одном компьютере @NathanTuggy – Zach
Привязка клиентского сокета до подключения не требуется и может быть плохой идеей. – user4581301