Socket Programming -

Hey guys, yeh, im new to this site

so im creating a (server) program which uses sockets to send/recv information from another pc. I use MS XP if that is needed.

iv just got a couple questions:
1. which libaries are required (ive just got <ws2tcpip.h> RE sockets)

2. does accept() (or is it listen()?) wait for a connection or does it accept only the connections at that point in time (so i need to make my own loop?)

3. when i try to use close(MySocketFD) a compile error occurs: error C3861: 'close': identifier not found. I think this might be a problem with my libraries? (hence Q1)

4. does it matter if both the client & server send data before recv()ing any?
eg.
server > send "hello client" > client
client > send "hello server" > server
server > recv(...) from client
client > recv(...) from server
does any problem occur? what if I try to recv() data before the client/server sends it?


Sorry if these Q's appear newbish.
Thanks for your help in advance :)
My Server Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <ws2tcpip.h>
#include <iostream>

const char CONNECT_IP[] = "127.0.0.1";
const char CONNECT_PORT[] = "55000";

using namespace std;

int main( void )
{
	cout << "SERVER::\n\n";

	cout << "Discovering Winsock version... ";
	WSAData webservicesdata; //Declare WSAData
	WORD winsockVersion=MAKEWORD(2, 0); //Winsock 2.0
	cout << "Winsock version " << winsockVersion << " discovered.\n";

	cout << "Starting winsock... ";
	int err=WSAStartup(winsockVersion, &webservicesdata);
	if (err==-1)
	{
		cout << "Error Starting Winsock (v" << winsockVersion <<")\n";
	}else if (err==0){
		cout << "Complete.\n";
	}


	
	//Getaddrinfo - the info of a certain address
	struct addrinfo GivenHostInfo;
	struct addrinfo* PointerToSocketAddrResults;
	//Client addrinfo
	struct sockaddr_storage client_addr;
	socklen_t client_addr_size;

	memset(&GivenHostInfo, 0, sizeof GivenHostInfo);
	GivenHostInfo.ai_flags = AI_PASSIVE;
	GivenHostInfo.ai_family = AF_UNSPEC;
	GivenHostInfo.ai_socktype = SOCK_STREAM;


	//Obtain addrinfo and fill socketinfo object
	getaddrinfo(CONNECT_IP, CONNECT_PORT, &GivenHostInfo, &PointerToSocketAddrResults);
	

	//Create Socket File Descriptor (pointer to where the socket is in memory)
	cout << "Creating socket file descriptor... ";
	SOCKET MySocketFD = socket(PointerToSocketAddrResults->ai_family,PointerToSocketAddrResults->ai_socktype,PointerToSocketAddrResults->ai_protocol);
	if (MySocketFD != INVALID_SOCKET){cout << "Complete.\n";}else{cout << WSAGetLastError() << " - ERROR!\n";}


	
	//bind() the Socket to the specified port 
	cout << "Binding to Port<" << CONNECT_PORT << ">... "; 
	SOCKET binderr = bind(MySocketFD, PointerToSocketAddrResults->ai_addr, PointerToSocketAddrResults->ai_addrlen);
	if (binderr==-1){cout << WSAGetLastError() << " - ERROR!\n";}else{cout << "Complete.\n";}

	//listen() on specified port
	cout << "Listening on Port<" << CONNECT_PORT << ">... ";
	SOCKET listenErr = listen (MySocketFD, 1);
	if (listenErr == -1 || listenErr == INVALID_SOCKET){cout << WSAGetLastError() << " - ERROR!\n";}else{cout<< "Complete.\n";}

	//accept() a connection on the specified port
	cout << "Accepting client connection on Port<" << CONNECT_PORT << ">... ";
	client_addr_size = sizeof client_addr;
	SOCKET ClientSocketFD = accept(MySocketFD,(struct sockaddr *)&client_addr,&client_addr_size);
	if (ClientSocketFD == -1){cout << WSAGetLastError() << " - ERROR!\n";}else{cout << "Complete.\n";}

	//send() a piece of data
	cout << "Sending information... ";
	int sendData = send(ClientSocketFD,"Hello World!",13,0);
	if (sendData == -1){cout << WSAGetLastError() << " - ERROR!\n";}else{cout << "Complete.\n";}

	//recv() a piece of data
	cout << "Receiving information... ";
	char DataFromClient;
	int recvData = recv(ClientSocketFD,&DataFromClient,20,0);
	if (recvData == -1){cout << WSAGetLastError() << " - ERROR!\n";}else{cout << "Complete.\n";}


	//Close all connections
	cout << "Closing connections... ";
	shutdown(MySocketFD,2);
	shutdown(ClientSocketFD,2);
	cout << "Complete.\n";

	//Free dynamicly allocated addrinfo
	cout << "Freeing Address Info... ";
	freeaddrinfo(PointerToSocketAddrResults);
	cout << "Complete.\n";

	//Clean up Winsock
	cout << "Cleaning Up WinSock... ";
	int socketcleanup = WSACleanup();
	if (socketcleanup == 0){cout << "Complete.\n";}else{cout << WSAGetLastError() << " - ERROR!\n";}


	system("PAUSE");
	return 0;
}


I've fixed my code, and run it, works fine. BUT, when I try to view which ports are open on my computer, (cmd > netstat) it does not display my port there! :( Does anyone know why this is?

thanx
Last edited on
nvm, fixed that problem too. (used netstat -a instead). So ive created a client to connect to the port. It returns WSA error 10013 (WSAEACCES)

Permission denied.

An attempt was made to access a socket in a way forbidden by its access
permissions.

Anyone know what the problem seems to be? And more importantly, how to fix it? (Ive tried running as Admin).
code:
1
2
3
4
5
6
7
8
9
const char CONNECT_IP[] = "127.0.0.1";
const char CONNECT_PORT[] = "55000"; // Do I need htons????
//start winsock 2.0, getaddrinfo, create socket...
if((connect(ClientSocketFD,PointerToSocketAddrResults->ai_addr,PointerToSocketAddrResults->ai_addrlen))==-1)
	{
		cout  << "Client Connection ERROR! - " << WSAGetLastError() << endl;
	}else{
		cout << "Connected to SERVER. on Port " << CONNECT_PORT << endl;
	}


Whats the problem(s) with my code? anything i need to add?
Last edited on
Hmm...well I'm not completely sure if how you are using connect is correct...I've always followed this tutorial:

http://johnnie.jerrata.com/winsocktutorial/

I'm pretty sure you want/need a str_addr struct (something like that).
I found out that my code works fine on Windows XP, just not Vista >:@ .

now Ive got another problem, Im trying to send "Hello World!" to the client & server. when I send() the data, it says the 13 bytes were sent. when i recv() the data, only 1 byte is recv()ed. This is because im using a char as a buffer, which will only hold 1 byte. But how do I use something bigger? (and preferably more secure than a character array.) recv() wants a char *!

Ive tried using a string, which of course fails.

my code:
1
2
3
4
5
6
//create socket blah blah.........

cout << "Receiving information... ";
		string DataFromServer; //where the data from server is stored
		int recvData = recv(ConnectingSocketFD,&DataFromServer,strlen(DataFromServer.c_str()),0); //recv the data
		if (recvData == -1){cout << WSAGetLastError() << " - ERROR!\n";}else{cout << "Complete. Recieved \"" << DataFromServer.c_str() << "\" (" << recvData << " bytes) from SERVER.\n";}


error output:
error C2664: 'recv' : cannot convert parameter 2 from 'std::string *' to 'char *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


what can I do to recv() more than 1 byte at a time? (simple i know, just cant figure it out :( ) Also, does anyone know how to make it work on Vista as well?
Last edited on
Topic archived. No new replies allowed.