c++ socket timeout error when trying to connect - c++

I've recently into c/c++ socket programming so I just made simple program that server and client respond each other. My server is in VMware( linux fedora) and client is windows(in visual studio 2017).
And it worked(pls notice that server and client are in one laptop)..
I also tried same client code with another computer(my deskTop) and got a WSAETIMEDOUT(10060)
error. The error was captured in connect() function in client code.
I have no idea how to solve :(
Could anybody help me?
Here's a client code
#include <iostream>
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
using namespace std;
#define DEFAULT_BUFLEN 512
int main(int argc, char *argv[]) {
WSADATA wsaData;
SOCKET connectSocket;
SOCKADDR_IN servAddr;
char sendBuf[DEFAULT_BUFLEN];
char recvBuf[DEFAULT_BUFLEN];
char nickName[DEFAULT_BUFLEN];
int recvLen = 0;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "start up error";
exit(1);
}
connectSocket = socket(PF_INET, SOCK_STREAM, 0);
if (connectSocket == INVALID_SOCKET) {
cout << "socket creation error";
exit(1);
}
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(connectSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
cout << "connect error: " << WSAGetLastError();
exit(1);
}
while (1) {
recvLen = recv(connectSocket, recvBuf, sizeof(recvBuf), 0);
if (recvLen > 0) {
if (strcmp(recvBuf, "Exit") == 0)
break;
cout << recvBuf;
//cin >> nickName;
cin.getline(nickName, DEFAULT_BUFLEN);
send(connectSocket, nickName, sizeof(nickName),0);
}
else if (recvLen == 0)
cout << "Connection closed";
else if (recvLen == -1)
cout << "Connection failed";
}
closesocket(connectSocket);
WSACleanup();
return 0;
}
Blockquote
and server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <iostream>
#include <string>
#define DEFAULT_LEN 512
#define DEFAULT_CLIENT_NUM 30
using namespace std;
char nickNameCommand[]="Please set your nickName:";
void error_handling(char * message);
class Client {
private:
char nickName[DEFAULT_LEN];
int clientSock;
public:
struct sockaddr_in clnt_addr;
int& getClientSock(){
return clientSock;
}
};
class Server {
private:
int serv_sock;
char informClientNickName[DEFAULT_LEN] = "Your NickName is ";
public:
Server(){
}
char message[DEFAULT_LEN]= "";
char clientNickName[DEFAULT_CLIENT_NUM][DEFAULT_LEN];
struct sockaddr_in serv_addr;
void setServSock(int value){
serv_sock = value;
}
int getServSock(){
return serv_sock;
}
void setInformClientNickName(int clientNum){
strcat(informClientNickName,clientNickName[clientNum]);
strcat(message , informClientNickName);
}
char* getInformClientNickName(){
return informClientNickName;
}
};
int main(int argc,char * argv[])
{
Client clientSocket[DEFAULT_CLIENT_NUM];
Server server;
int clientNum=0;
int recvLen=0;
socklen_t clnt_addr_size;
char message[DEFAULT_LEN];
if(argc!=2)
{
printf("Usage: %s <port>\n",argv[0]);
exit(1);
}
server.setServSock(socket(PF_INET,SOCK_STREAM,0));
if(server.getServSock() == -1)
error_handling("socket() error");
memset(&(server.serv_addr),0,sizeof(server.serv_addr));
server.serv_addr.sin_family=AF_INET;
server.serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server.serv_addr.sin_port=htons(atoi(argv[1]));
if(bind(server.getServSock(),(struct sockaddr*)&
(server.serv_addr),sizeof(server.serv_addr)) ==-1)
error_handling("bind() error");
if(listen(server.getServSock(),5)==-1)
error_handling("listen() error");
clnt_addr_size=sizeof(clientSocket[0].clnt_addr);
while(1) {
clientSocket[clientNum].getClientSock() = accept(server.getServSock(),
(struct sockaddr*)&(clientSocket[clientNum].clnt_addr),&clnt_addr_size);
if(clientSocket[clientNum].getClientSock()==-1)
error_handling("accept() error");
else{
write(clientSocket[clientNum].getClientSock(),nickNameCommand,sizeof(nickNameCommand));
read(clientSocket[clientNum].getClientSock(),(void*)(server.clientNickName[clientNum]),DEFAULT_LEN);
}
cout << "Received name is : " << server.clientNickName[clientNum]<<endl;
clientNum++;
cout << "ClientNum: " << clientNum <<endl;
recvLen=0;
for(int i=0;i<clientNum;i++){
server.setInformClientNickName(i);
write(clientSocket[clientNum].getClientSock(),server.message,sizeof(server.message));
}
}
for(int i=0;i<clientNum;i++)
close(clientSocket[i].getClientSock());
close(server.getServSock());
return 0;
}
void error_handling(char * message)
{
fputs(message,stderr);
fputc('\n',stderr);
exit(1);
}

Related

UDP client can not recieve data from server in C++

I am new for C++. I tried to write a UDP client and server in C++. The server can receive data from client. But the client can not receive data from server. No matter what data the server sends, the method recvfrom in client always returns 0.
The client code is below:
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024
int main()
{
SOCKET sock_Client;
WSADATA WSAData;
char receBuf[BUFFER_SIZE];
char sendBuf[BUFFER_SIZE];
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
printf("initialation fails!");
return -1;
}
sock_Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
SOCKADDR_IN addr_server;
addr_server.sin_family = AF_INET;
addr_server.sin_port = htons(4567);
addr_server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
SOCKADDR_IN sock;
int len = sizeof(sock);
while (true)
{
cout << "input data to send:";
cin >> sendBuf;
sendto(sock_Client, sendBuf, strlen(sendBuf), 0, (SOCKADDR*)&addr_server, sizeof(SOCKADDR));
//int last=recv(sock_Client, receBuf, strlen(receBuf), 0); //
int last = recvfrom(sock_Client, receBuf, strlen(receBuf), 0, (SOCKADDR*)&sock, &len);
if (last > 0)
{
receBuf[last] = '\0';
if (strcmp(receBuf, "bye") == 0)
{
cout << "server stops talking..." << endl;
closesocket(sock_Client);
break;
}
else
{
printf("received data:%s\n", receBuf);
}
}
}
closesocket(sock_Client);
WSACleanup();
return 0;
}
The server code:
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
#define BUFFER_SIZE 1024
int main()
{
WSADATA WSAData;
char receBuf[BUFFER_SIZE];
char Response[BUFFER_SIZE];
if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0)
{
printf("initialation fails!");
exit(1);
}
SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockServer == INVALID_SOCKET)
{
printf("Failed socket() \n");
return 0;
}
SOCKADDR_IN addr_Server;
addr_Server.sin_family = AF_INET;
addr_Server.sin_port = htons(4567);
addr_Server.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(sockServer, (SOCKADDR*)&addr_Server, sizeof(addr_Server)) == SOCKET_ERROR)
{
printf("Failed socket() %d \n", WSAGetLastError());
return 0;
}
SOCKADDR_IN addr_Clt;
int fromlen = sizeof(SOCKADDR);
while (true)
{
int last = recvfrom(sockServer, receBuf, 1024, 0, (SOCKADDR*)&addr_Clt, &fromlen);
if (last > 0)
{
receBuf[last] = '\0';
if (strcmp(receBuf, "bye") == 0)
{
cout << " client stop talking..." << endl;
closesocket(sockServer);
return 0;
}
else
{
printf("received data(%s):%s\n", inet_ntoa(addr_Clt.sin_addr), receBuf);
}
}
cout << "anser client:";//<br>Response = “”;
cin >> Response;
sendto(sockServer, Response, strlen(Response), 0, (SOCKADDR*)&addr_Clt, sizeof(SOCKADDR));
}
closesocket(sockServer);
WSACleanup();
return 0;
}
Anyone know what is wrong with the code?
The code runs in Windows. So, set(CMAKE_CXX_STANDARD 14) has to be added into CMakeLists.txt. If you want to run the code, please notice that.

OpenSSL in C++ Socket Connection (HTTPS Client)

i wrote an script, who can create an connection to an HTTP Server and shows the content of the website in the console.
Very easy.
But i want to connect to an https server and do the same procedures.
I searched at google and didn't found what i searched.
Please help me and give me an tutorial who can i use the openssl library.
I tried myself on the openssl library, but the library is very complicated and difficult to understand.
Here is my code of the http client:
#include <iostream>
#include <ctype.h>
#include <cstring>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <string>
#include <arpa/inet.h>
#include <openssl/ssl.h>
using namespace std;
int sock;
struct sockaddr_in client;
int PORT = 80;
int main(int argc, char const *argv[])
{
bzero(&client, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons( PORT );
client.sin_addr.s_addr = inet_addr("172.16.0.6");
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
cout << "Error creating socket." << endl;
exit(1);
}
if ( connect(sock, (struct sockaddr *)&client, sizeof(client)) < 0 ) {
close(sock);
cout << "Could not connect" << endl;
exit(1);
}
stringstream ss;
ss << "GET /" << "\r\n"
<< "Host: 172.16.1.4\r\n"
<< "Accept: application/json\r\n"
<< "Connection: close"
<< "\r\n\r\n";
string request = ss.str();
if (send(sock, request.c_str(), request.length(), 0) != (int)request.length()) {
cout << "Error sending request." << endl;
exit(1);
}
char cur;
while ( read(sock, &cur, 1) > 0 ) {
cout << cur;
}
return 0;
}
Here is a sample SSL client that connects to https://about.google/intl/en/ and prints downloaded a page : SSLClient.cpp
//============================================================================
// Name : SSLClient.cpp
// Compiling : g++ -c -o SSLClient.o SSLClient.cpp
// g++ -o SSLClient SSLClient.o -lssl -lcrypto
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <string.h>
using namespace std;
SSL *ssl;
int sock;
int RecvPacket()
{
int len=100;
char buf[1000000];
do {
len=SSL_read(ssl, buf, 100);
buf[len]=0;
printf("%s\n",buf);
// fprintf(fp, "%s",buf);
} while (len > 0);
if (len < 0) {
int err = SSL_get_error(ssl, len);
if (err == SSL_ERROR_WANT_READ)
return 0;
if (err == SSL_ERROR_WANT_WRITE)
return 0;
if (err == SSL_ERROR_ZERO_RETURN || err == SSL_ERROR_SYSCALL || err == SSL_ERROR_SSL)
return -1;
}
}
int SendPacket(const char *buf)
{
int len = SSL_write(ssl, buf, strlen(buf));
if (len < 0) {
int err = SSL_get_error(ssl, len);
switch (err) {
case SSL_ERROR_WANT_WRITE:
return 0;
case SSL_ERROR_WANT_READ:
return 0;
case SSL_ERROR_ZERO_RETURN:
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
default:
return -1;
}
}
}
void log_ssl()
{
int err;
while (err = ERR_get_error()) {
char *str = ERR_error_string(err, 0);
if (!str)
return;
printf(str);
printf("\n");
fflush(stdout);
}
}
int main(int argc, char *argv[])
{
int s;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
printf("Error creating socket.\n");
return -1;
}
struct sockaddr_in sa;
memset (&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("173.194.222.139"); // address of google.ru
sa.sin_port = htons (443);
socklen_t socklen = sizeof(sa);
if (connect(s, (struct sockaddr *)&sa, socklen)) {
printf("Error connecting to server.\n");
return -1;
}
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
const SSL_METHOD *meth = TLSv1_2_client_method();
SSL_CTX *ctx = SSL_CTX_new (meth);
ssl = SSL_new (ctx);
if (!ssl) {
printf("Error creating SSL.\n");
log_ssl();
return -1;
}
sock = SSL_get_fd(ssl);
SSL_set_fd(ssl, s);
int err = SSL_connect(ssl);
if (err <= 0) {
printf("Error creating SSL connection. err=%x\n", err);
log_ssl();
fflush(stdout);
return -1;
}
printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
char *request = "GET https://about.google/intl/en/ HTTP/1.1\r\n\r\n";
SendPacket(request);
RecvPacket();
return 0;
}
Note that if you want to exchange data between client and server with openssl, you might need to process error codes SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE as described in documentation. But it's not necessary here as HTTPS protocol is serial.

Sockets: Why is accept() hanging but connect() is succeeding?

I have been trying to understand why on my server the accept() call is still blocking when the client has a successful connect() call?
server.cpp
#include <errno.h>
#include <strings.h>
#include <iostream>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
/* Function for printing error */
void report_error(char *s)
{
printf("receiver: error in%s, errno = %d\n", s, errno);
exit(1);
}
int main(int argc, char *argv[])
{
int s,c;
int res;
struct sockaddr_in socket_address = {0}, client_sa = {0};
unsigned int client_sa_len = sizeof(client_sa);
/* Creating the socket and returns error if unsuccesfull */
if((s= socket(AF_INET, SOCK_DGRAM, PF_UNSPEC)) == -1)
report_error("socket");
socket_address.sin_family = AF_INET;
socket_address.sin_addr.s_addr=INADDR_ANY;
socket_address.sin_port = htons(5318 + 2000);
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&socket_address, sizeof(socket_address))== -1)
report_error("bind");
listen(s, 10);
cout << "listening on port\n";
while(1)
{
/*The server just hangs here*/
c = accept(s, (struct sockaddr*)&client_sa, &client_sa_len);
if (c > 0)
{
cout << "LOG: Was the accept successful" << endl;
res = fork();
if (res < 0)
{
perror("Forking of child failed");
}
}
if(res == 0)
{
//close(s);
char msg[MSGL], reply[50], args[MSGL];
char command[MSGL];
cout << "LOG: Get message?" << endl;
GetRequest(msg, c, &client_sa);
if( (msg[0] == 'c') && (msg[1] == 'd') && (msg[2] == ' '))
{
strncpy(command, "cd", sizeof(command));
int arg_i = 0;
for(int i = 3; msg[i] != '\n'; ++i)
{
args[arg_i] = msg[i];
++arg_i;
}
}
else
{
for(int i = 0; msg[i] != '\n'; ++i)
{
command[i] = msg[i];
}
}
else
{
if(c > 0)
{
//close(c);
}
}
}
return 0;
}
When I run this server it prints that it is listening, then when I initialize the client it does not say that the client has connected
client.cpp
#include <errno.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include "globals.h"
using namespace std;
/* Declaring errno */
extern int errno;
int main(int argc, char *argv[])
{
int s;
char* server_address = argv[1];
char command[MSGL];
char reply[MSGL];
int connect_success;
struct sockaddr_in sa = {0} ,cli_sa = {0};
int length = sizeof(sa);
struct hostent *hp;
cli_sa.sin_family = AF_INET;
cli_sa.sin_addr.s_addr=INADDR_ANY;
cli_sa.sin_port = htons(5318 + 2001);
/* FILL SOCKET ADDRESS*/
if((hp = gethostbyname(server_address))==NULL)
report_error("gethostbyname");
bcopy((char*)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
//memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
sa.sin_port = htons(5318 + 2000); /* define port number based on student ID*/
/* Creating the socket and returns error if unsuccessfull */
if((s=socket(AF_INET, SOCK_DGRAM, PF_UNSPEC))== -1)
report_error("socket");
/* Binding the socket and returns error if unsuccesfull */
if(bind(s, (struct sockaddr *)&cli_sa, sizeof(cli_sa))== -1)
report_error("bind");
connect_success = connect(s,(struct sockaddr*) &sa, length);
cout << connect_success << endl;
if (connect_success < 0)
{
report_error("connect");
cout << "LOG: is there an error?" << endl;
}
cout << "LOG: is the connection made?" << endl;
while(1)
{
cout << "myRPC>>";
fgets(command,MSGL,stdin);
if (DoOperation(command,reply,s,sa) == SEND_FAILURE)
{
cout << "Error: sending command\n";
}
}
return 0;
}
I'm fairly certain that your server process has undefined behavior.
accept() and connect() is for TCP sockets. You are creating UDP sockets. For UDP sockets, all that connect() does is set the default address for send(), and it always succeeds immediately. This is explained in the manual page for connect(2), which you should definitely read:
If the socket sockfd is of type SOCK_DGRAM, then addr is the address
to which datagrams are sent by default, and the only address from
which datagrams are received.
I expect accept() to fail for UDP (SOCK_DGRAM) sockets, most likely with EINVAL. If you review the logic in your server code, when accept() fails, res never gets initialized before its value is tested in the if() statement.
Undefined behavior.

socket programming: 'accept: Bad file descriptor'

I'm trying to write a game that will let multiple clients connect and play - below is the relevant code (it's very messy - cleaning up later):
Edit: I realized it's a lot of scrolling... the crash occurs towards the end of the game during:
std::cout << black_hits << " black hits & " << white_hits
<< " white hits.\n";
if (black_hits == 4) {
std::cout << "you won!\n";
std::cin.ignore().get();
close(client); //<<<< CRASH HERE
return 0;
}
Not really a crash I guess... but close enough :)
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <string>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define BACKLOG 10
#define MAXDATASIZE 100
typedef enum {RED,GREEN,BLUE,YELLOW,ORANGE} color;
int StartMasterMind(int client, sockaddr_storage addr_in);
struct msgstruct {
int length;
char* send_data;
};
void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int tcp_connect(const char *serv, const char *host = NULL)
{
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr; // connector's address information
socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(host, serv, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}
freeaddrinfo(servinfo); // all done with this structure
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("server: waiting for connections...\n");
while(1) { // main accept() loop
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}
inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);
if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
//if (send(new_fd, "Hello, world!", 13, 0) == -1)
// perror("send");
//close(new_fd);
StartMasterMind(new_fd,their_addr);
// exit(0);
}
close(new_fd); // parent doesn't need this
}
return 0;
}
void InitializeGame(const char* port)
{
tcp_connect(port);
}
std::vector<color> GetInputAsColorMap(char* input)
{
[...]//redacted for clarity
}
int StartMasterMind(int client, sockaddr_storage addr_in)
{
struct msgstruct message;
struct sockaddr_storage their_addr = addr_in;
socklen_t addr_len;
message.send_data = "Welcome to ... M A S T E R M I N D.\n";
message.length = strlen(message.send_data);
send(client, message.send_data, message.length, 0);
[...]//redacted for clarity
if (strcmp(theValue, "random") == 0 || strcmp(theValue, "Random") == 0)
{
[...]//redacted for clarity
}
else
{
[...]//redacted for clarity
}
char* buf;
for (int i = 0; i < 8; ++i) {
std::vector<color> current_try(4);
int black_hits = 0, white_hits = 0;
std::vector<int> correctColorIndex;
std::vector<int> correctColor;
bool exclude[4] = {false};
std::cout << "test\n";
message.send_data = "Please enter your guess: ";
message.length = strlen(message.send_data);
send(client, message.send_data, message.length, 0);
addr_len = sizeof their_addr;
std::cout << "addr_len: " << addr_len << std::endl;
recvfrom(client, buf, MAXDATASIZE-1, 0, (struct sockaddr *)&their_addr, &addr_len);
current_try = GetInputAsColorMap(buf);
std::cout << "the buffer: " << buf << std::endl;
std::cout << "current_try: " << current_try[0] << current_try[1] << current_try[2] << current_try[3] << std::endl;
[...]//redacted for clarity
std::cout << black_hits << " black hits & " << white_hits
<< " white hits.\n";
if (black_hits == 4) {
std::cout << "you won!\n";
std::cin.ignore().get();
close(client); //<<<< CRASH HERE
return 0;
}
}
[...]//redacted for clarity
}
int main(int argc, char** argv)
{
InitializeGame(argv[1]);
return 0;
}
Here is sample output:
server: waiting for connections...
server: got connection from 127.0.0.1
value or random:
1122
test
addr_len: 128
the buffer: 1123�
current_try: 1123
3 black hits & 0 white hits.
test
addr_len: 128
the buffer: 1223�
current_try: 1223
2 black hits & 1 white hits.
test
addr_len: 128
the buffer: 1122�
current_try: 1122
4 black hits & 0 white hits.
you won!
accept: Bad file descriptor
accept: Bad file descriptor
accept: Bad file descriptor
... // continuously, hundreds of times
I'm very new to socket programming; could someone give me a hand? This crashes with or without trying to close(client) at the end of the game.
I think when the child process is wrapping back to start of while(1) loop, it tries to accept a connection with server socket descriptor = "sockfd" which you already closed for the child:
if (!fork()) { // this is the child process
close(sockfd);
....
}
Try this link to read as how to terminate the child process after its work is complete.
That message means that you're calling accept() on an invalid file descriptor, i.e. probably one that you've closed.

How to make a full-duplex c++ winsock chat program

I'm trying to make a simple client-server chat program in C++. I wrote this, but my problem is that I can just send data from the server to the client. I want to have a full-duplex communication, and send data from client to server too.
Here is my code.
server :
#include "stdafx.h"
#include <WinSock2.h>
#include <winsock.h>
#include <stdio.h>
#include <iostream>
#include <string>
#define RCVBUFSIZE 32
using namespace std;
#pragma comment(lib, "Ws2_32.lib")
int main()
{
WSADATA wsadat;
SOCKET welcome_socket = INVALID_SOCKET;
string IpAddress;
int PortNom;
SOCKADDR_IN SockAddress;
//-----------------------------------------------
if (WSAStartup(MAKEWORD(2,2),&wsadat) !=NO_ERROR)
{
cout << "WSA intialization failed. \n";
WSACleanup();
return 1;
}
//------------------------------------------------
welcome_socket = socket(AF_INET , SOCK_STREAM , 0);
//--------------------------------------------------
cout << "Enter your ip address: ";
cin >> IpAddress;
cout << "Enter your port nomber:";
cin >> PortNom;
//---------------------------------------------------
SockAddress.sin_addr.s_addr = inet_addr (IpAddress.c_str());
SockAddress.sin_port = htons(PortNom);
SockAddress.sin_family = AF_INET;
//---------------------------------------------------
bind(welcome_socket,(SOCKADDR *)&SockAddress,sizeof(SockAddress));
listen(welcome_socket,1);
//----------------------------------------------------
SOCKET Comm_sock;
SOCKADDR_IN ClientAddr;
int AddressLen = sizeof (ClientAddr);
char *buffer = new char[13];
int turn= 0;
char* buf = new char[50];
char temp;
while (true)
{
Comm_sock = accept(welcome_socket,(SOCKADDR *)&ClientAddr , &AddressLen);
while (buf != "exit")
{
if (turn == 0)
{
cout << endl;
recv(Comm_sock,buf,50,0);
if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')
return 0;
cout << "MsG from client :"<< buf << endl;
cin.get(temp);
turn = 1;
}
if (turn == 1)
{
cout << "Enter MsG:";
cin.get(buf,50);
if (buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')
return 0;
send(Comm_sock,buf,strlen(buf)+1,0);
cin.get(temp);
turn=0;
}
}
}
and client:
#include "stdafx.h"
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
#include <iostream>
using namespace std;
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "12345"
//-------------------------------------
int main ()
{
WSADATA wsadata;
int iResult;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientservice;
char *sendbuf ="";
char recvbuf[DEFAULT_BUFLEN];
char sendbuffer[512];
int recvbuflen = DEFAULT_BUFLEN;
int sendbuflen = 512;
//----------------------------------
iResult = WSAStartup(MAKEWORD(2,2),&wsadata);
//----------------------------------
ConnectSocket = socket(AF_INET,SOCK_STREAM , IPPROTO_TCP);
//-----------------------------------
clientservice.sin_family = AF_INET;
clientservice.sin_addr.s_addr = inet_addr( "127.0.0.1" );
clientservice.sin_port = htons( 11111 );
//-----------------------------------
iResult = connect (ConnectSocket,(SOCKADDR *)&clientservice ,sizeof(clientservice));
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
cout << "bytes Sent:" << iResult << "\n";
//-------------------------------------
iResult = shutdown(ConnectSocket ,SD_SEND);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
do {
string reciev;
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
recvbuf[iResult]= 0 ;
cout << recvbuf << endl;
} while(true);
//------------------------------------------
closesocket(ConnectSocket);
WSACleanup();
}