-
Socket coding...
I seem to remember a tutorial a while back probably years at this point that was very straight forward about playing with sockets... It was very simple although it could only send 256 chars worth of data at one time. I am curious if anyone knows of a simple server class not the win api one all I would like is to send messages back and forth between computers. I know it encapsulated the API I want to say it was winsock 2 as well... Has some interesting functions like HasData() to see if the socket had data waiting to be read, bind, connect, send, recv, select(to some degree) ,connect, initalize, and shutdown. I remember getting the source in a tutorial I found was some ninja-like game where you basicly swung a sword around and jumped around... any help finding these files would be appreciated. I just want to mess around with some code tomorrow and this would be a great help.
-
Welp gave up searching decided to program my own... Very simple socket wrapper seems to work too tested it with telnet I believe they use ' ' as a delimiter but it works none the less. I do have a question though why can't I make fd_set socks a static var in the class? I mean it is just a struct right? It gave me some errors when I did that though...
Code:
#ifndef MYSOCKET_H
#define MYSOCKET_H
#include <winsock2.h>
#include <stdio.h>
class mysocket
{
public:
~mysocket();
mysocket(int);
bool Startup(); //Shall call WSAStartup for us and error check.
bool Connect(char* ip, short port);
int Send(char* ); //Sends a char string out.
char* Recv(); //Recvs a char string.
bool Listen(short port); //listens to the socket to see if someone wants to connect.
int Accept(); //accepts connections on a socket returns the ientifier to the socket.
void assign(int fd);
bool HasData(); //Lets us know if there is data waiting to be read on the socket.
void Shutdown(); //Close WSA down properly to be called exclusively at the end of a program.
private:
SOCKET s;
fd_set socks;
};
#endif
Code:
#include "mysocket.h"
mysocket::mysocket(int fd)
{
s = fd;
}
bool mysocket::Startup() //Shall call WSAStartup for us and error check. Returns false on fail.
{
WSADATA wsadata;
int error = WSAStartup(0x0202, &wsadata);
if(error)return 0; //did not initalize
if(wsadata.wVersion != 0x0202)
{
WSACleanup();
return 0; //wrong version
}
return 1;
}
bool mysocket::Connect(char* ip, short port)
{
SOCKADDR_IN host;
host.sin_family = AF_INET;
host.sin_port = htons(port);
host.sin_addr.s_addr = inet_addr(ip);
s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s == INVALID_SOCKET)return false;
if(connect(s,(SOCKADDR *)&host, sizeof(host)) == SOCKET_ERROR)return false;
else return true;
}
int mysocket::Send(char *text) //Sends a char string out.
{
return send(s,text,strlen(text),0);
}
char* mysocket::Recv() //Recvs a char string.
{
char *buffer;
buffer = new char[1024];
memset(buffer, 0, sizeof(buffer)); //Clear the buffer
//Put the incoming text into our buffer
recv (s, buffer, 1023, 0);
return buffer;
}
bool mysocket::Listen(short port) //Puts the socket in listening mode. Use HasData() to check it for connections.
{
int reuse_addr = 1;
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
s = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if(s == INVALID_SOCKET)return false;
//added later
setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (char *)&reuse_addr,sizeof(reuse_addr));
//end
if(bind(s,(LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
return false;
listen(s, SOMAXCONN);
return true;
}
int mysocket::Accept() //accepts connections on a socket returns the file descriptor to the socket.
{
int connection; /* Socket file descriptor for incoming connections */
/* We have a new connection coming in! */
connection = accept(s, NULL, NULL);
if (connection < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
printf("\nConnection accepted: FD=%d", connection);
return connection;
}
bool mysocket::HasData() //Lets us know if there is data waiting to be read on the socket.
{
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1;
FD_ZERO(&socks);
FD_SET(s,&socks);
select(s,&socks,NULL,NULL,&timeout);
if(FD_ISSET(s,&socks))return true;
else return false;
}
mysocket::~mysocket()
{
closesocket(s);
}
void mysocket::Shutdown() //Close WSA down properly to be called exclusively at the end of a program.
{
WSACleanup();
}
void mysocket::assign(int fd) //plan to overload = soon just testing things atm.
{
s = fd;
}
Code:
//IMPLEMENTATION simple echo server.
#include <winsock2.h>
#include <iostream.h>
#include <stdio.h>
#include "mysocket.h"
int main(void)
{
mysocket test;
test.Startup();
test.Listen(27115);
while(!test.HasData());
mysocket connection(test.Accept());
while(1)
{
if(connection.HasData())
{
char *text = connection.Recv();
cout<<"Incoming text: "<<text<<endl;
if(text[0] == 'q')break;
connection.Send("Use 'q' to quit");
delete text;
}
}
test.Shutdown();
return 0;
}
-
Code:
bool mysocket::Send(char *text) //Sends a char string out.
{
send(s,text,sizeof(text),0);
}
Says it returns bool, returns nothing; does not check the result of send(); sizeof(text) is just plain wrong as it will always be the size of a character pointer.
This one line function alone suggests you should not be messing with sockets until you have some more advanced (or should I say, early intermediate) understanding of C++.
-
Note that I don't even check the return in main since it is echoing back from a telnet issue. As for the bool yea it should return a value. Still don't know why can't I make fd_set socks; static in the class? I mean it is just a struct to show what descriptors are ready to be written to I think? I know there is a write variable and an exception one as well. strlen instead of sizeof worked wonders as well on the send function as well...