I am learning socket programming for use in an upcoming project, and I have researched the issue pretty extensively. Basically, all this program needs to is on a client computer (locally, i.e. my computer) needs to connect to a remote server and send a command (which it has done, I have gotten it to read back Apache server stats to me).
What is happening is this: I believe I have the socket set right, but the server receives random garbage buffers (one of which consisted of " '>Z"). I have tried various socket settings, different bindings, etc.
I have in the process of starting it will initialize winsock, create a socket, bind the network, and then do a listen loop and while(1) recv data.
I have yet to get the server (on a remote computer, hosted at a datacenter) to output the message. This is my only goal for the time being. I appreciate everyone's help in advance, and the code is before (this is the entire code, sorry for the length).
Client Code:
char *host = "127.0.0.1";
SOCKET clientsock;
struct sockaddr_in server_address;
struct hostent *host_info;
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData) != -1) {
cout << "WINSOCK2 Initialized" << endl;
if((clientsock = socket(AF_INET, SOCK_STREAM, 0)) != SOCKET_ERROR) {
cout << "Socket Created" << endl;
char opt[2];
opt[0] = 0;
opt[1] = 1;
//setsockopt(clientsock, SOL_SOCKET, SO_BROADCAST, opt, sizeof(opt));
host_info = gethostbyname(host);
server_address.sin_family = AF_INET;
server_address.sin_addr = *((struct in_addr *)host_info->h_addr);
server_address.sin_port = htons(80);
if(connect(clientsock, (struct sockaddr *)&server_address, sizeof(struct sockaddr)) == 0) {
cout << "Connected to host" << endl;
char COMMAND[22] = "SVR --WINSOCK-VERIFY\0";
if(send(clientsock, COMMAND, sizeof(COMMAND), 0)) {
cout << "Command Sent" << endl;
closesocket(clientsock);
}
else {
cout << "ERROR - Could not send command. " << "Error: " << WSAGetLastError() << endl;
closesocket(clientsock);
WSACleanup();
}
}
else {
cout << "ERROR - Could not connect to host. " << "Error: " << WSAGetLastError() << endl;
closesocket(clientsock);
WSACleanup();
}
}
else {
cout << "ERROR - Could not create the socket. " << "Error: " << WSAGetLastError() << endl;
WSACleanup();
}
}
else {
cout << "ERROR - Could not initialize WINSOCK2. " << "Error: " << WSAGetLastError() << endl;
WSACleanup();
}
Server Code:
SOCKET serversock;
char *server = "127.0.0.1";
//char *server = "50.31.1.180";
struct sockaddr_in server_address;
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,2), &WSAData) != -1) {
cout << "WINSOCK2 Initialized" << endl;
if((serversock = socket(PF_INET, SOCK_DGRAM, PF_UNSPEC)) != SOCKET_ERROR) {
cout << "Socket Created" << endl;
unsigned long NB = 1;
ioctlsocket(serversock, FIONBIO, &NB);
server_address.sin_family = AF_INET;
server_address.sin_addr = *((struct in_addr *)server);
server_address.sin_port = htons(21578);
if(bind(serversock, (struct sockaddr*)&server_address, sizeof(struct sockaddr) == 0)) {
cout << "Network bound" << endl;
cout << "Listening..." << endl;
listen(serversock, 5);
while(1) {
int size = sizeof((struct sockaddr *)server);
SOCKET clientsock = accept(serversock, (struct sockaddr *)server, &size);
char INCOMMAND[20];
if(clientsock >= 0) {
if(recv(clientsock, INCOMMAND, sizeof(INCOMMAND), 0)) {
int i = 0;
if(INCOMMAND == "SVR --WINSOCK-VERIFY\0") {
cout << "SVR receieved" << endl;
}
while(INCOMMAND[i] != '\0') {
cout << INCOMMAND[i];
i++;
}
cout << endl;
}
else {
cout << "ERROR - Could not receive command" << endl;
break;
}
}
}
}
else {
cout << "ERROR - Could not bind network. " << "Error: " << WSAGetLastError() << endl;
closesocket(serversock);
WSACleanup();
}
}
else {
cout << "ERROR - Could not create the socket. " << "Error: " << WSAGetLastError() << endl;
WSACleanup();
}
}
else {
cout << "ERROR - Could not initialize WINSOCK2. " << "Error: " << WSAGetLastError() << endl;
WSACleanup();
}
Calls to send/recv may not send/receive the amount of bytes you indicate in their third argument, in fact, most of the time they will send/receive less bytes than you expect. You usually have to loop until the entire data has been sent/received. Also note that doing this:
char buffer[100];
recv(clientsock, buffer, sizeof(buffer), 0);
cout << buffer;
Will most surelly print garbage, since you don't have a null terminator in your char array(whatch out for buffer overflows when appending it), and you're not checking the return value of recv. It might be reading 1 byte only(or none if an error ocurred). You're printing your buffer the same way in your server app.
In this case, you are actually sending the null-terminator, but since you might read less bytes than you expect, this character might not be received by the other application, thus printing it will print garbage chars.
Edit: You should have a look at the structure of a sockaddr struct. You can have a look at it here. In your code you are using this convertion:
int size = sizeof((struct sockaddr *)"127.0.0.1");
const char *, which is the type of "127.0.0.1", cannot be casted to a sockaddr pointer, they're incompatible. Here you should use getaddrinfo in order to resolve the IP address(note that you could use a domain name, and this function would resolve it). There are lots of tutorials online on how to use this function, just search for "getaddrinfo".
Related
I'm new to C++ Socket and my Server can't send message to its client. The send() function return -1 always and it seems to have a problem with accpSocket. However Client can do that smoothly and I don't know what's wrong. Please help me thank you so much!
Server
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#include<sdkddkver.h>
#include<winsock.h>
using namespace std;
int main() {
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
int port = 2403;
WSADATA wsaData;
int wsaerr;
//Step 1: Set up dll
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);
if (wsaerr)
cout << "The winsock dll not found";
else {
cout << "The winsock dll found\n";
cout << "Winsock dll status: " << wsaData.szSystemStatus << endl;
}
//Step 2: Set up server socket
serverSocket = INVALID_SOCKET;
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
cout << "Error at socket: " << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Server socket successfull!\n";
//Step 3: Binding socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.S_un.S_addr = INADDR_ANY;
service.sin_port = htons(port);
if (bind(serverSocket, (sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) {
cout << "Binding failed! " << WSAGetLastError();
return 0;
}
else
cout << "Binding complete!\n";
// Step 4: Listen to the connections
if (listen(serverSocket, 1) == SOCKET_ERROR) {
cout << "Listen failed! " << WSAGetLastError();
return 0;
}
else
cout << "Waiting for connections ...";
SOCKET accpSocket = accept(serverSocket, NULL, NULL);
if (accpSocket == INVALID_SOCKET) {
cout << "Accepting failed! " << WSAGetLastError();
WSACleanup();
return -1;
}
else
cout << "Accept connection!\n";
char recvMess[2000];
char sendMess[2000];
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
cout << "Client: " << recvMess << endl;
cout << "Server: ";
cin.getline(sendMess, 2000);
int bytesend = send(acceptSocket, sendMess, 2000, 0);
if (bytesend <= 0)
cout << "Unsent";
return 0;
}
Client
#include<iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
using namespace std;
int main() {
int port = 2403;
WSADATA wsaData;
int wsaerr;
SOCKET clientSocket;
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);
if (wsaerr)
cout << "Winsock dll not found!";
else {
cout << "Winsock dll is ok!\n";
cout << "Status: " << wsaData.szSystemStatus << endl;
}
clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
cout << "Set up client socket failed" << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Set up complete!\n";
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_port = htons(port);
if (inet_pton(clientService.sin_family, "127.0.0.1", &clientService.sin_addr) <= 0) {
cout << "Invalid address!";
return -1;
}
if ((connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService))) == SOCKET_ERROR) {
cout << "Connection failed!\n";
WSACleanup();
return 0;
}
else
cout << "Connection complete!\n";
char sendMess[2000];
char recvMess[2000];
cout << "Client: ";
cin.getline(sendMess, 2000);
int bytesend = send(clientSocket, sendMess, 2000, 0);
int byterecv = recv(clientSocket, recvMess, 2000, 0);
if (byterecv <= 0)
cout << "Nothing";
else
cout << "Server" << recvMess << endl;
return 0;
}
int bytesend = send(acceptSocket, sendMess, 2000, 0);
is not sending to a connected socket. acceptSocket was defined at the top of main and then ignored up until the call to send
As a general rule of thumb, keep variable definition close to first use.
In the server at
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Killlllll meeeeee!!!!
remove acceptSocket to prevent future mistakes and in
int bytesend = send(acceptSocket, sendMess, 2000, 0);
replace acceptSocket with the socket that was actually accepted, accpSocket.
Side notes:
Never ignore the return codes.
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
could fail and return -1 or return 0 if the socket was disconnected, yet the program will still
cout << "Client: " << recvMess << endl;
And worse, there's no guarantee that recvMess will be null-terminated, recv on a streaming socket gives you what the socket has available or becomes available up to the maximum number of bytes requested, so if there is any data read, make sure byterecv is a valid index in recvMess by only reading sizeof(recvMess) - 1 bytes and then forcing termination with recvMess[byterecv] = '\0'; before printing.
send(acceptSocket, sendMess, 2000, 0); sends all 2000 bytes of sendMess regardless of how many bytes were read with cin.getline(sendMess, 2000);. Use
send(acceptSocket, sendMess, cin.gcount(), 0);
instead. Add on an extra byte (cin.gcount() + 1) if you want to send the null terminator.
I was not able to find what I was doing wrong on the internet.
My problem is that, recvfrom() function seems to remember the last value instead of making new calls and getting my buffer updated.
I've created the same code logic with Python and it works just find but I can't find a way to do the same in C++.
So that's my code :
#define _WINSOCKAPI_
#include <windows.h>
#include <winsock2.h>
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <stdio.h>
#include <time.h>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main()
{
cout << "\t\t--------------UDP Server ---------------" << endl;
cout << endl;
WSADATA WinSockData;
int iWsaStartup, iWsaCleanup;
SOCKET UDPSocketServer;
struct sockaddr_in UDPClient;
char Buffer[200];
int iBind, iReceiveFrom;
int iUDPClientLen = sizeof(UDPClient);
int iCloseSocket;
int response, offset;
ULONG cmd = 0;
iWsaStartup = WSAStartup(MAKEWORD(2, 2), &WinSockData);
if (iWsaStartup != 0) {
cout << "WSAStartup Failed" << endl;
}
cout << "WSAStartup Success" << endl;
//Setting Socket connexion information
UDPClient.sin_family = AF_INET;
UDPClient.sin_addr.s_addr = htons(INADDR_ANY);
UDPClient.sin_port = htons(40100);
//Informations to send to this address
const char* msg = "///";
size_t msg_length = sizeof(msg) - 1;
struct sockaddr_in myaddr;
memset(&myaddr, 0, sizeof(myaddr));
myaddr.sin_addr.s_addr = inet_addr("192.128.20.65");
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(40100);
//Create Socket
UDPSocketServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (UDPSocketServer == INVALID_SOCKET) {
cout << "Socket creation failed with error : " << WSAGetLastError() << endl;
WSACleanup();
exit(0);
}
cout << "Socket creation success" << endl;
//Binding Socket to INADDR_ANY 0.0.0.0:40100
iBind = bind(UDPSocketServer, (SOCKADDR*)&UDPClient, sizeof(UDPClient));
if (iBind == SOCKET_ERROR) {
cout << "Binding failed with error : " << WSAGetLastError() << endl;
closesocket(UDPSocketServer);
WSACleanup();
exit(0);
}
cout << "Binding success" << endl;
//Make sure the socket is blocking
if (ioctlsocket(UDPSocketServer, FIONBIO, &cmd) == SOCKET_ERROR) {
cout << "ioctlsocket failed with error : " << WSAGetLastError() << endl;
}
else
cout << "ioctlsocket success : " << cmd << endl; //Return 0 because it is set for Blocking
//Send information to 192.128.20.65:40100
response = sendto(UDPSocketServer, reinterpret_cast<const char*>(msg), msg_length, 0, (sockaddr*)&myaddr, sizeof(myaddr));
if (response == SOCKET_ERROR) {
cout << "Send failed with error : " << WSAGetLastError() << endl;
}
cout << "Send success : " << response << endl;
//Wait 4 seconds
Sleep(4000);
//Send information to 192.128.20.65:40100
response = sendto(UDPSocketServer, reinterpret_cast<const char*>(msg), msg_length, 0, (sockaddr*)&myaddr, sizeof(myaddr));
if (response == SOCKET_ERROR) {
cout << "Send failed with error : " << WSAGetLastError() << endl;
}
cout << "Send success : " << response << endl;
while (1) {
//Capture receive data from any address on port 40100
//This is supose to be a blocking function but it never block after the first return call
iReceiveFrom = recvfrom(UDPSocketServer, Buffer, sizeof(Buffer) + 1, MSG_PEEK, (SOCKADDR*)&UDPClient, &iUDPClientLen);
if (iReceiveFrom == SOCKET_ERROR) {
cout << "Receive failed with error : " << WSAGetLastError() << endl;
}
else if (iReceiveFrom != 0) {
Buffer[iReceiveFrom] = '\0'; //Add end of line to Buffer
//printf("%.*s\n", iReceiveFrom, Buffer);
cout << "Receive success : " << Buffer << endl;
}
}
iCloseSocket = closesocket(UDPSocketServer);
iWsaCleanup = WSACleanup();
if (iWsaCleanup == SOCKET_ERROR) {
cout << "WSA Cleanup failed with error : " << WSAGetLastError() << endl;
}
cout << "WSA Cleanup success" << endl;
system("PAUSE");
return 0;
}
I've created a UDP C++ socket that binds itself to 0.0.0.0:40100 and listens to that port using the function recvfrom().
The problem is that my recvfrom() function seems to never update or wait for new data. It just sends over the same old data without waiting.
I've tried to add some code that will change all the value of the buffer, but when recvfrom() is called the value recieved is the same as the old one.
From what I've read, recvfrom() function is supposed to be a blocking function, but in my case, it doesn't seems to work.
I've made sure the function was blocking by looking at ioctlsocket() function response; it's set to 0, so it's supposed to block.
I've also tried to create a new socket for my sendTo() function and I got the same result.
Finally, I've also tried to remove the sendTo() functions, but like my code in Python, no data seems to comeback from the socket if I don't send the string in the first place. (Wireshark shows that there's data that is sent to this port at all the time. Without this initialization, I can't get anything to print on my socket).
I find it strange that data is recieved on a certain port on my computer but when bind to that port I can't see this data before sending data to the address that send it in the first place. So I think the problem might happens between the sendTo() call and the recvfrom().
Using MSG_PEEK with recvfrom doesn't remove the data from the incoming data queue, it's still there the next time you call recvfrom.
I have finished my c++ tutorial and went to winsock, but still a bit new to the subject. I made a client code that tried to connect to a website using port 80 (http) but whenever i run it i get an error code 10049 and it doesn't connect to the server. Here is the code..
Defenitions.h:
#include <iostream>
#include <winsock2.h>
using namespace std;
//Prototypes:
WORD version = MAKEWORD(2, 2);
WSADATA info;
SOCKET hSocket;
USHORT port;
sockaddr_in hSockAddr;
char website[50];
void initWSA();
void createSocket();
hostent* websiteInfo;
void getPort();
void connectSocket();
void cleanUp();
//Functions:
void initWSA(){
if(WSAStartup(version, &info) == 0){
cout << "WinSock initialization successful!" << endl;
}else{
cout << "WinSock initialization failed!" << endl;
}
}
void createSocket(){
hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(hSocket != INVALID_SOCKET){
cout << "Socket Creation Successful!" << endl;
}else{
cout << "Socket Creation Failed!" << endl;
}
}
void getPort(){
cout << "Enter the port number to connect to:" << endl;
}
void connectSocket(){
if(connect(hSocket, (SOCKADDR*)&hSockAddr, sizeof(hSockAddr)) == 0){
cout << "Connection to server successful!" << endl;
}else{
cout << "Connection to server failed! error code: " << WSAGetLastError() << endl;
}
}
void cleanUp(){
if(closesocket(hSocket) == 0){
cout << "Socket Closure Successful!" << endl;
}else{
cout << "Socket Closure Failed!" << endl;
}
if(WSACleanup() == 0){
cout << "WinSock cleanup successful!\a" << endl;
}else{
cout << "WinSock cleanup failed!\a" << endl;
}
}
main.cpp:
#include "Definitions.h"
int main(int argc, char *argv[]){
initWSA();
createSocket();
cout << "IP Address of: " << "www.google.com" << " is: "<< gethostbyname("www.google.com") << endl;
getPort();
cin >> port;
hSockAddr.sin_family = AF_INET;
hSockAddr.sin_port = htons(port);
hSockAddr.sin_addr.S_un.S_addr = inet_addr("www.google.com");
connectSocket();
cleanUp();
return 0;
}
This is always what i get:
Any suggestions?
The problem is with how you convert host address to ip,
inet_addr is for ip addresses:
The inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure.
instead of:
hSockAddr.sin_addr.S_un.S_addr = inet_addr("www.google.com");
use:
struct hostent *he = gethostbyname("www.google.com");
memcpy(&hSockAddr.sin_addr, he->h_addr_list[0], he->h_length);
// Or:
//hSockAddr.sin_addr.s_addr = ((in_addr *)(he->h_addr))->s_addr;
see here: converting host to ip by sockaddr_in gethostname etc
[edit]
As Remy Lebeau has written in comment, gethostbyname is depracated and getaddrinfo should be used instead, below is sample code using getaddrinfo:
// Resolve host name
struct addrinfo hints, *servinfo, *p;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int rv;
std::string str_port = std::to_string(port);
if ((rv = getaddrinfo("www.google.com", str_port.c_str(), &hints, &servinfo)) != 0) {
std::cerr << "getaddrinfo: " << rv << ": " << gai_strerrorA(rv) << std::endl;
return 1;
}
// Loop over all returnd addresses, first one that works is the one we want to use
for (p = servinfo; p != NULL; p = p->ai_next) {
createSocket();
if (connect(hSocket, p->ai_addr, p->ai_addrlen) == 0) {
cout << "Connection to server successful!" << endl;
break;
}
else {
cout << "Connection to server failed! error code: " << WSAGetLastError() << endl;
closesocket(hSocket);
}
}
freeaddrinfo(servinfo);
See Windows Sockets Error Codes, in this case:
WSAEADDRNOTAVAIL
10049
Cannot assign requested address.
The requested address is not valid in its context. This normally results from an attempt to bind to an address that is not valid for the local computer. This can also result from connect, sendto, WSAConnect, WSAJoinLeaf, or WSASendTo when the remote address or port is not valid for a remote computer (for example, address or port 0).
Did you see your IP address output? I think it's not what you want.
I think you should see this example in order to get the IP address:
Winsock Programmer’s FAQ
Examples: Get the Local IP Address(es)
I found some code in the internet with some basics about creating an TCP/IP server in C++.
I took this code, added some libraries and some lines of code. The result is, that I am able to compile and run the code/server in Qt Creator on Windows as a console program. Nevertheless I am not able to connect to the server because it just runs through the code without waiting and accepting a connection from an TCP client.
This is the code:
EDIT: Code is updated and it's now working. Test against == -1 is the solution.
#define PORT 2000
#define MAX_QUEUE 5
#define BUF_SIZE 1024
int main(int argc, char* const argv[])
{
cout << "Hello World!" << endl;
WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
cout << "wsaret: " << wsaret << endl;
cout << "Start TCP/IP Server" << endl;
/* file descriptors for sockets */
SOCKET sock_1, sock_2; //switched from in to SOCKET //unsigned int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];
//struct sockaddr_in server;
struct sockaddr_in server;
/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//if(sock_1 < 0)
if(sock_1 == -1)
{
cout << "socket: " << WSAGetLastError() << endl; //instead of //cout << "socket: " << strerror(errno) << endl; //cout << "socket wsaret: " << wsaret << endl;
exit(1);
}
/* build address in internet domain */
server.sin_family = AF_INET;
/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = htons(2000); //server.sin_port = PORT; //Port: 2000
/* bind socket */
//if(bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
int bindreturn = (bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
if(bindreturn == -1)
{
cout << "bind: " << WSAGetLastError() << endl; //instead of //cout << "bind: " << strerror(errno) << endl; //cout << "bind wsaret: " << wsaret << endl;
exit(1);
}
listen(sock_1,MAX_QUEUE);
/* start accepting connection */
sock_2 = accept(sock_1,0,0);
if(sock_2 < 0)
{
cout << "accept: " << WSAGetLastError() << endl;
exit(1);
}
/* read from sock_2 */
while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
{
if(rec_value < 0)
{
cout << "recv: " << WSAGetLastError() << endl;
exit(1);
}
else
{
cout << "else" << endl;
send(sock_2,"1,2,3",strlen("1,2,3"),0);
}
}
cout << "Ending connection" << endl;
closesocket(sock_1);
closesocket(sock_2);
cout << "End TCP/IP Server" << endl;
WSACleanup();
return 0;
}
The console shows the following after/during running the program in one or less seconds:
Hello World!
wsaret: 0
Start TCP/IP Server
bind: 0
What can I do, that the server waits for an connection partner?
Thanks in advance.
Regards
matl
Edit: Added a few lines of code at the beginning, which I forgot before.
Edit: Code update
Edit: Code update
I'm going to comment in detail on the original code you posted.
cout << "Start TCP/IP Server" << endl;
//int sock_1,sock_2; /* file descriptors for sockets */
int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];
//struct sockaddr_in server;
sockaddr_in server;
/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//0);
Missing test here. You must test the result for -1 along these lines:
if (sock_1 == -1)
{
cout << "socket creation error: " << WSAGetLastError() << endl;
exit(1); // or some other measure to prevent continuation
}
Back to your code:
/* build address in internet domain */
server.sin_family = AF_INET;
/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = PORT; //Port: 2000
That should be
server.sin_port = htons(PORT);
Back to your code:
/* bind socket */
int bindreturn = bind(sock_1, (struct sockaddr *)&server, sizeof(server));
cout << "bindreturn: " << bindreturn << endl;
Inadequate. Here again you need to test for -1, and print WSAGetLastError() and exit if you got it.
listen(sock_1,MAX_QUEUE);
Untested. Here again you need to test for -1 etc.
/* start accepting connection */
//system("pause");
sock_2 =accept(sock_1,0,0);
//system("pause");
cout << "acceptreturn: " << sock_2 << endl;
Inadequate again, see above.
/* read from sock_2 */
while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
{
if(rec_value<0)
{
cout << "error: " << rec_value << endl;
exit(1);
}
Test is incorrect. A system call indicates error by returning exactly -1, not just any value < 0. A socket FD for example returned by socket() or accept() can be negative, or any value other than -1.
else
{
cout << "else" << endl;
send(sock_2,"1,2,3",strlen("1,2,3"),0);
}
}
closesocket(sock_1);
closesocket(sock_2);
cout << "End TCP/IP Server" << endl;
return 0;
It is apparent from the closesocket() calls that you're using Winsock, in which case both WSAStart() and WSACleanup() are missing.
How is PORT defined?
You should use:
server.sin_port = htons(PORT); //Port: 2000
Is your IP-address correct?
All your calls are receiving SOCKET_ERROR (-1), so you should check lasterror to get more information.
Not sure (on Windows here), but shouldn't those be unsigned int's?
int sock_1, sock_2;
Update:
Ok, you seem to be using Qt on Windows.
For Qt, you might as well use the Qt libraries.
On Windows in general, you could use the free MS Visual Studio.
You also need to call WSAStartup() like this:
WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
// check wsaret
// more code here
WSACleanup();
Also use SOCKET:
SOCKET sock_1, sock_2;
Check the errorcodes with WSAGetLastError().
I'm trying to make a simple chat program between to programs on a lan. My problem is I can easily connect and send message from the server to client but not the other way around. I'm trying to make it work like this. Server<->Client as in constantly sending and receiving between both programs, obviously that would require a loop for continuous input but I'm not quite sure how to do it. Here is the code for both server and client.
//THIS IS THE SERVER
int main(int argc, char *argv[])
{
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0)
{
cout << "WSADATA Failed to startup!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;
}
cout << "WSADATA Startup Successful!" << endl;
SOCKET mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock == INVALID_SOCKET)
{
cout << "Socket Creation Failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;
}
cout << "Socket Creation Successful!" << endl;
sockaddr_in sin;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
if (bind(mysock,(sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
cout << "Socket failed to bind!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;
}
cout << "Socket Binded Successfuly!" << endl;
//Listen to the socket until successful on receiving input
while (listen(mysock, SOMAXCONN) == SOCKET_ERROR);
SOCKET client;
int lin = sizeof(sin);
client = accept(mysock,(sockaddr*) &sin, &lin);
cout << "Connection Established!" << endl;
char buf[200] = "Message from server to client\n";
//Send an initial message to the client
send(client, buf, sizeof(buf), 0);
//but then how do I wait for a message from the client again here??
//ive tried recv here before with no luck :/
closesocket(mysock);
closesocket(client);
WSACleanup();
system("pause >nul");
return 0;
}
//Client program here
int main(int argc, char *argv[])
{
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0)
{
cout << "WSADATA startup has failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;
}
cout << "WSADATA Startup Successful!" << endl;
SOCKET mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock == INVALID_SOCKET)
{
cout << "Socket Creation Failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;
}
cout << "Socket Creation Successful!" << endl;
sockaddr_in sin;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");//ip for connection
sin.sin_family = AF_INET;
if (connect(mysock,(sockaddr*)&sin, sizeof(sin)) == INVALID_SOCKET)
{
cout << "Socket Connection Failed" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
closesocket(mysock);
WSACleanup();
return 0;
}
cout << "Socket Has Connected Successfuly!" << endl;
//Same applies here, receive message but exactly how do I send one back
char buf[200];
recv(mysock, buf, sizeof(buf), 0);
cout << buf;
//send here seemed to bring up a bunch of symbols
system("pause >nul");
WSACleanup();
closesocket(mysock);
return 0;
}
If you want full-duplex communication (i.e. both server and client sides able to send and receive at any time), you can either use multiple threads (which I don't recommend, since multithreading introduces race conditions and deadlocks unless you really know what you are doing), or use non-blocking I/O, multiplexed using select() or poll() or similar. With multiplexing, you basically tell the select()/poll() call "don't return until something interesting happens", where "something interesting" is defined as "data arrived on a socket", or (if you have data to send) "there is now buffer space available on a socket to place some outgoing data into". Then when select()/poll() returns, you examine what events have been flagged as ready, call send()/recv() as appropriate (these calls won't ever block since you set the sockets to non-blocking-I/O mode), and then go back to sleep inside select()/poll() again until the next events occur.
In this way your program is able to handle both send() and recv() efficiently, without spinning the CPU and without every having recv() hold off send() (or vice versa).
take a look at here:
Client-Server communiation
But also you have to be familiar with multithreading, because in this link-example you have infinite loops in client and server examples that listens for incoming messages, so you have to put them in thread and you will be able to send and listen messages asynchronously. If you don't put them in thread you won't be able to send and receive messages asynchronously, because infinite loops block all operations beyond them.
I think this is the most simpliest way to establish communication.