RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

3d Party Utility(Sockets)

ABTOP

Sorceror
3d Party Utility(Sockets)

Hi, i'll try makesome programm between server & client. It mean client send packet, this programm catch it and send to server, then catch response and send to client.
I looking through uo protocol. But there are only packet structures. I think if i don't create new client i won't use that structures. UO client will send all necessary packets.
So when i try listen UO client i catch one packet 4 byte. I think it is Encrypted Login Seed. But after server doesn't give any response. And im confused how correctly i must listen sockets for catch and send all necessary packets.
Thanks.
 

Smjert

Sorceror
ABTOP;803077 said:
Hi, i'll try makesome programm between server & client. It mean client send packet, this programm catch it and send to server, then catch response and send to client.
I looking through uo protocol. But there are only packet structures. I think if i don't create new client i won't use that structures. UO client will send all necessary packets.
So when i try listen UO client i catch one packet 4 byte. I think it is Encrypted Login Seed. But after server doesn't give any response. And im confused how correctly i must listen sockets for catch and send all necessary packets.
Thanks.

I think you should show some of your code... otherwise we can't help you.
 

ABTOP

Sorceror
Ok i'll post code later. We create that prog on another machine.
But main idea is:
UO Client connect to 1999 port.
My programm create server(listen socket) and listen 1999 port
also connect to 2593 port(to RunUO server)
as soon as it catch some message from client it redirect to server.
so
Code:
connect(...); //To RunUO server
CreateThread(....); //Create new thread for listening

void Listen(void*)
{
        bind(...);    //To 1999 port
        listen(...);  //1999 port
        accept(...); //Client connected and save client data

        while(1)
        {
                   recv(...); //Receive message from client
                   send(...); //Send message to server
[COLOR="Blue"]                   recv(...); //Receive answer from server
                   send(...); //Send back to client[/COLOR]
         }
}
Im not sure about blue part but anyway programm stops working after send message to server.
When i run this programm and run Client and RunUO i got this data:
RunUO:
Connected [1]
UO Client:
try to log in
My prog:
Received from client: .... length 4
Send to server
That all. So server or doesn't receive that message or doesn't answer.
Im not sure why client send encrypted seed and what send next. Or need receive 2 meesages first?
1 - seed
2 - login attempt
?

===================
Here is code
Code:
sockaddr_in server, client, answer; // Для хранения адреса
SOCKET server_socket, client_socket,answserver_socket;

int WINAPI Listen(LPVOID lpParameter)
{
	cout<<"bind\t\t\t";
	if (bind(server_socket, (LPSOCKADDR)&server, sizeof(server)) == SOCKET_ERROR) 
	{
		cout<<"error"<<endl;
		closesocket(server_socket);
		WSACleanup();
		return 1;
	}
	else
		cout<<"ok"<<endl;

	// 4. Устанавливаем сокет в режим прослушивания
	cout<<"listen\t\t\t";
	if (listen(server_socket, 5) == SOCKET_ERROR)
	{
		cout<<"error"<<endl;
		closesocket(server_socket);
		WSACleanup();
		return 1;
	}
	else	
		cout<<"ok"<<endl;

	int a = sizeof(answer);
	char msg[1024];

	cout<<"accepted\t\t";
	if( (answserver_socket = accept(server_socket, (sockaddr*)&answer, &a) ) == INVALID_SOCKET)
		cout<<"error "<<WSAGetLastError()<<endl;
	else
		cout<<"ok"<<endl;
	
[COLOR="Blue"]	while(true)
	{
	cout<<"================="<<endl;
		memset(&msg,0,sizeof(msg));
		recv(answserver_socket,msg, sizeof(msg), 0);
		send(client_socket, msg, strlen(msg)+1, 0 );
		recv(client_socket, msg, sizeof(msg), 0); 
		send(answserver_socket, msg, strlen(msg), 0 );
		/*if (msg != NULL)
			cout<<msg<<endl;*/
	}[/COLOR]

	return 0;
};

void Init()
{
//	cout<<"\t\t\t\tSERVER"<<endl;

	// 1. Инициализируем сокеты (требуем версию 1.1 как минимум)
	cout<<"WSA\t\t\t";
	if (WSAStartup(0x202, &wsa_data) != 0) 
	{
		cout<<rus("не инециализирован")<<endl;
		return;
	}
	else
		cout<<"ok"<<endl;

	// 2. Открываем серверный сокет
	cout<<"socket\t\t\t";
	server_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (server_socket == INVALID_SOCKET) 
	{
		cout<<"error"<<endl;
		return;
	}
	else
		cout<<"ok"<<endl;

	client_socket = socket(AF_INET, SOCK_STREAM, 0);

	// 3. Привязываем сокет к адресу
	memset(&server, 0, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	server.sin_port = htons(1999);

	memset(&client, 0, sizeof(client));
	client.sin_family = AF_INET;
	client.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	client.sin_port = htons(2593);

	cout<<"connect\t\t\t";
	if( connect(client_socket, (LPSOCKADDR)&client, sizeof(client)) != SOCKET_ERROR )
		cout<<"ok"<<endl;
	else
		cout<<"error "<<WSAGetLastError()<<endl;

	CreateThread(NULL, 1024, (LPTHREAD_START_ROUTINE)Listen, NULL, 0, &id);
}
 

arul

Sorceror
You can't treat the received message like a string, since as we know UO uses custom packet-based protocol. The strlen function will return at the first occurence of the '\0' character.

The return value of the recv function is the amount of actually received bytes.
 

ABTOP

Sorceror
Ok so change to
Code:
int size = recv(...);
send(client_socket,msg, size);
And how i need recv data? like what? structure? For each packet different structure.
Also if i send strlen(msg) server doesnt answer. But if send more RunUO disconnect me
Encrypted client detected
Disconnected [0]
 

arul

Sorceror
Just receive the data and forward them to the client. Which is still a wrong way of doing this. Take a look how UOAI or UO Machine works.
 

ABTOP

Sorceror
Hmm it's too hard for me. Im not pretty good at socket scripting. So now i want know only how send and receive packets. And where my mistakes.
 

Smjert

Sorceror
But are you using razor to load the client (and decrypt it)?
Otherwise it's obvious that the server didn't respond, it doesn't support encrypted client.
If you want to, you have to have the latest svn and use this script(check also what i wrote in the thread).
 

ABTOP

Sorceror
I use uo_rice for decrypt client.
Any way i need help to understand how to receive packets.
Client i think first send Encrypted seed and then login attempt packet. Is that mean i need catch 2 packets from client. Because if i catch only 1 server doesnt receive login attempt packet.
 

Smjert

Sorceror
ABTOP;803157 said:
I use uo_rice for decrypt client.
Any way i need help to understand how to receive packets.
Client i think first send Encrypted seed and then login attempt packet. Is that mean i need catch 2 packets from client. Because if i catch only 1 server doesnt receive login attempt packet.

Oh ok, good.
So a way to do this is to write code for the login, so you know that after sending 4byte packet you don't have to wait server answer, otherwise you need a new thread.
On the main one you put recv and send to the client, and on the other recv and send for RunUO server, because your problem is that you have blocking recv and send.
Another way could be asynchronous recv and send, so again is something that doesn't block the execution.
 

ABTOP

Sorceror
Im not sure why i need second thread?
recv - no actions until recv message from client
send - now we 100% recv something and send it to server
here server must give answer recv - take answer
send - and sent it to client
It's one thread.

I don't know why client doesn't generate right packets for attempt log in.
 

arul

Sorceror
This whole idea of 'proxy' server is bad from the very beginning. Really, take a look at UOAI, where you can do the same packet manipulation on a few lines, in C/C++, VB, C# ... whatever supports COM.
 

ABTOP

Sorceror
Thanks but i need this program. If this is really hard so i'll stop and continue my education.
And i ask help in send, recv already generated packets by UO Client. And UOAI and UO Machine uses own generated packets. It's play big role.
 

Smjert

Sorceror
When the server receive your seed packet it doesn't send to you nothing, so your recv call blocks the execution, this is why you need 2 threads.
Remember also that not always the server send something when receive something from the client.
You must be able to recv and send dinamically.
 

ABTOP

Sorceror
Smjert;803164 said:
When the server receive your seed packet it doesn't send to you nothing, so your recv call blocks the execution, this is why you need 2 threads.
Remember also that not always the server send something when receive something from the client.
You must be able to recv and send dinamically.
Can you please show some code. Im not quite understand what you mean. If server doesn't send nothing so how i can recv call block the execution. And what is that block?

Thx i'll check UO Proxy
 

Smjert

Sorceror
Send function stops the execution until it sends all the data of the buffer you passed.
Recv function stops the execution until it receive one byte at least.

So what happens with your code is this:

Recv() // Here the function stops the execution until the 4 byte packet arrives, then it goes forward
Send() // Here the function stops the execution until the 4 byte packet is sent to the server, then it goes forward
Recv() // Here again the function stops the execution, waiting for something that will never arrives because server doesn't answer to the 4 byte packet.
Send() // The execution never arrives here

So what you have to do is to have 2 separate loops, one for Recv/Send of the client and the other for the server.
Since they need to be looped together you need a new thread (so now check for POSIX Thread or Win32 Thread, it depends if it has to be portable or not).
 

ABTOP

Sorceror
Recv() // Here again the function stops the execution, waiting for something that will never arrives because server doesn't answer to the 4 byte packet.

why you think server doesn't answer? When my prog will send 4bytes to server it will wait for answer. So if server give some answer prog will receive this.
If you mean that my prog blocked others packets it can't. Because even i try recv more than 1 packet in first connect i still get maximum 2 successfully recv. And 2nd i can't call packet it's something like "A1".

And if i will make 2 threads i'll get:
1 thread:.............................in this time.............................2 thread:
Recv from Server...........................................................................Send global var
put in global var..............................................................................Recv answer
....................................................................................................Send to Client
I get same case.
 

Smjert

Sorceror
It's simple, you have to look at RunUO code... LoginServerSeed doesn't send you back nothing.

Also sorry but it's not the same case (with //// i mean its the same thing)

thread1(client):-------------------------thread2(server):
Recv() -----------------------------------Recv() // They both wait for something
Send() -----------------------------------//// // Something arrived from client, then you send it to the server, thread2 is still waiting for something
Recv() -----------------------------------//// // We wait for the next part of the login packets, thread2 is still waiting for something
Send()------------------------------------//// // Something arrived from client, send to server, thread2 is still waiting for something
Recv()------------------------------------Send() // Wait again for other packets, finally server received a valid login and send back packets to client

So what you need are 2 seperate threads, also please note that they don't have to be synchronized.
 
Top