Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
lawliet93
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
1

Клиент-сервер. Клиент не принимает данные

06.12.2012, 12:29. Просмотров 2966. Ответов 4

Здравствуйте о светлейшие умы сего мира! Я работаю над одним проектом, а именно написание многопользовательской онлайн игры, и собственно есть клиент и сервер. Клиент написан на движке, который в свою очередь написан на C#. Задача у меня стоит такая. В клиенте есть стандартная форма входа, где нужно ввести свой логин и пароль, и нажать кнопку отправить. После чего клиентское приложение связывается с сервером и передает логин и пароль в формате - %login&password%. Сервер разделяет эти данные и вытягивает собственно сам логин и пароль, после чего делает запрос к базе данных, на проверку существования такой комбинации логина и пароля, если такая комбинация существует, то из той же таблицы БД, в которую делался запрос, вытягивает значение поля ID которое соответствует комбинации логина и пароля. После чего сервер отправляет ID клиенту, в формате - success login=id.
Проблема вот в чем: значение Available клиентского сокета всегда равно нулю. То есть, данные от клиента отправляются, сервер их правильно принимает, делает правильный запрос к БД и получает верный ответ от БД, и вроде нормально отправляет данные клиенту, но вот клиент эти данные никак принять не может. А в чем ошибка, не совсем понимаю, так как код клиента писал не с нуля, а на основе уже работающего клиента. Собственно прошу помочь в решении этой проблемы.
Код клиента
C#
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
 
public class login : MonoBehaviour {
    
    public GUIStyle style;
    public GUIStyle style_err;
    
    private static Rect log;
    private static Rect pass;
    
    private static Rect label_log;
    private static Rect label_pass;
    private static Rect label_error;
    private static bool switcher=false;
    
    private static Rect btn;
    
    private static string my_login="";   //переменная которая будет содержать логин
    private static string my_password="";//                                   пароль
    
    private static int id;
    
    /*Connecting block BEGIN*/
    private static Socket socket;
 
        private static SocketAsyncEventArgs SockAsyncEventArgs; // объект для асинхронной операции на сокете
 
        private static byte[] buff; // буфер обмена
        
        
 
 
        
    
    private static void Init()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            buff = new byte[256];
            SockAsyncEventArgs = new SocketAsyncEventArgs();
            // подписываемся на завершение асинхронного соединения
            SockAsyncEventArgs.Completed += SockAsyncArgs_Completed;
        }
    
     private static void SockAsyncArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            switch (e.LastOperation)
            {
                case SocketAsyncOperation.Connect:
                    ProcessConnect(e);
                    break;
                case SocketAsyncOperation.Receive:
                    ProcessReceive(e);
                    break;
            }
        }
    
     private static void Start_Connect(string address, int port)
        {
            SockAsyncEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(address), port);
            ConnectAsync(SockAsyncEventArgs);
        }
    
     private static void ConnectAsync(SocketAsyncEventArgs e)
        {
            bool willRaiseEvent = socket.ConnectAsync(e);
            if (!willRaiseEvent)
                ProcessConnect(e);
        }
    
     private static void ProcessConnect(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
                SockAsyncEventArgs.SetBuffer(buff, 0, buff.Length);
            else
                Debug.Log("Lost connection with "+ e.RemoteEndPoint.ToString()); //Debug.Log - вывод информации в консольное окно
 
        }
    
     private static void SendAsync(byte[] data)
        {
            if (socket.Connected && data.Length > 0)
            {
            Debug.Log("start sending");
                
                SocketAsyncEventArgs e = new SocketAsyncEventArgs();
                e.SetBuffer(data, 0, data.Length);
                e.Completed += SockAsyncArgs_Completed;
                bool willRaiseEvent = socket.SendAsync(e);
            }
            Debug.Log("End Sending");
            
        }
 
    private static void ProcessSend(SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                Debug.Log("Proc send");
                ReceiveAsync(SockAsyncEventArgs);
            }
            else
            {
                Debug.Log("Not sended");
            }
        }
    
     private static void ReceiveAsync(SocketAsyncEventArgs e)
        {
        Debug.Log("Rec Async");
            bool willRaiseEvent = socket.ReceiveAsync(e);
            if (!willRaiseEvent)
                ProcessReceive(e);
            Debug.Log("Proc Rec called");
        }
    
     private static void ProcessReceive(SocketAsyncEventArgs e)
        {
        Debug.Log("Rec");
            if (e.SocketError == SocketError.Success)
            {
 
                    string str = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
                    Debug.Log("Receive: "+str);
                
                    if(str.StartsWith("success"))
                {
                    switcher=false;
                    string[] split = str.Split(new Char[] {'='});
                    Debug.Log(split.Length);
                    Application.LoadLevel(1);
                }
                else
                {
                    switcher=true;
                }           
            
        }
    }
    
    
    /*Connecting block END*/
    
    // Use this for initialization
    void Start () {                       //данные о позиции и размерах элементов GUI                                
        log = new Rect(Screen.width/2-(Screen.width/100*20/2),Screen.height/2-50,Screen.width/100*20,20);
        pass=new Rect(Screen.width/2-(Screen.width/100*20/2),Screen.height/2-10,Screen.width/100*20,20);
        
        label_log=new Rect(Screen.width/2-(Screen.width/100*20/2)-(Screen.width/100*20/2),Screen.height/2-50,Screen.width/100*20/2,20);
        label_pass=new Rect(Screen.width/2-(Screen.width/100*20/2)-(Screen.width/100*20/2),Screen.height/2-10,Screen.width/100*20/2,20);
        
        btn=new Rect(Screen.width/2-(Screen.width/100*20/4),Screen.height/2+30,Screen.width/100*10,20);
        
        label_error=new Rect(Screen.width/2-(Screen.width/100*20/2),Screen.height/2+70,Screen.width/100*20,20);
    }
    
    // Update is called once per frame
    void Update () {
    
        
        
    }
    
    void OnGUI()           //отрисовка гуи, все операции в этой функции выполняются каждый кадр
    {
        GUI.Label(label_log,"Login: ",style);          
        my_login = GUI.TextField(log,my_login);
        GUI.Label(label_pass,"Password: ",style);       
        my_password = GUI.TextField(pass,my_password); 
        
        if(GUI.Button(btn,"Enter")){            //Если нажати кнопка Enter, то делаем следующее..
            
            Init(); //создаем соккет и все дела
            Start_Connect("127.0.0.1", 9390); //коннектимся к серверу
            
            try
        {
        SendAsync(Data(my_login,my_password)); //отправляем логин и пароль
        InvokeRepeating("send", Time.deltaTime, Time.deltaTime); //запускаем метод send() через Time.deltatime после запуска программы, повторяем запуск метода каждый Time.deltatime
                                                                // где Time.deltatime - скорость отрисовки 1 кадра. То есть если у нас 60 кадров в секунду, то Time.deltatime = 1/60.
        
        }
        catch(Exception e)
        {
            Debug.Log(e.Message);
        }
            
            /*//Debug.Log("i = "+i);
            if(i==0)
            {
                switcher=true;
            }
            else{
                switcher=false;
                Application.LoadLevel(1);
            }*/
        }
        if(switcher) //если true = пишем сообщение об ошибке
        {
            GUI.Label(label_error,"INCORRECT LOGIN OR PASSWORD",style_err);
        }
        
    }
    
    
    byte[] Data(string l, string p) // вставляем разделители и возвращаем буффер для отправки
    {
        byte[] buffer = Encoding.UTF8.GetBytes("%"+l+"&"+p+"%");
        Debug.Log("%"+l+"&"+p+"%");
        return buffer;
    }
    
     void send()    // если на сокет пришли какие-то данные, то получаем их
    {
        
        Debug.Log("socket value = "+socket.Available);
        if (socket.Available!=0)           //вот здесь socket.Available всегда = 0, почему-то
                    {
            
                        ProcessSend(SockAsyncEventArgs);
            }
   
}
}
Код сервера:
C#
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using MySql.Data.MySqlClient;
 
namespace ConsoleApplication3
{
    class Program
    {
        class ThreadedServer
        {
            private Socket _serverSocket;
            private int _port;
            private string db_connect = "Database=test_login;Data Source=localhost;User Id=server;Password=11111"; //информация для подключения к БД
            private int id;
 
            public ThreadedServer(int port) { _port = port; }
 
            public void Start()
            {
                SetupServerSocket();
                for (int i = 0; i < 10; i++)
                    _serverSocket.BeginAccept(new
                        AsyncCallback(AcceptCallback), _serverSocket);
            }
 
            private class ConnectionInfo
            {
                public Socket Socket;
                public byte[] Buffer;
 
            }
            private List<ConnectionInfo> _connections = new List<ConnectionInfo>();
 
            private void SetupServerSocket()
            {
              
                IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, _port);
 
 
                // Создаем сокет, привязываем его к адресу
                // и начинаем прослушивание
                _serverSocket = new Socket(
                    myEndpoint.Address.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);
                _serverSocket.Bind(myEndpoint);
                _serverSocket.Listen((int)
                    SocketOptionName.MaxConnections);
 
            }
 
            private void AcceptCallback(IAsyncResult result)
            {
                ConnectionInfo connection = new ConnectionInfo();
                try
                {
                    // Завершение операции Accept
                    Console.WriteLine("Подключился чел");
                    Socket s = (Socket)result.AsyncState;
                    connection.Socket = s.EndAccept(result);
                    connection.Buffer = new byte[256];
                    lock (_connections) _connections.Add(connection);
 
                    // Начало операции Receive и новой операции Accept
                    connection.Socket.BeginReceive(connection.Buffer,
                        0, connection.Buffer.Length, SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        connection);
                    _serverSocket.BeginAccept(new AsyncCallback(
                        AcceptCallback), result.AsyncState);
                }
                catch (SocketException exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Socket exception: " +
                        exc.SocketErrorCode);
                }
                catch (Exception exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Exception: " + exc);
                }
            }
 
            private void ReceiveCallback(IAsyncResult result)
            {
                ConnectionInfo connection =
                    (ConnectionInfo)result.AsyncState;
                try
                {
                    int bytesRead =
                        connection.Socket.EndReceive(result);
                    if (0 != bytesRead)
                    {
                        lock (_connections)
                        {
                            string req = Encoding.UTF8.GetString(connection.Buffer, 0, connection.Buffer.Length);
                            Console.WriteLine(req);
                            if (req.StartsWith("%")) //если сообщение начинается с %, то...
                            {
                                string[] split = req.Split(new Char[] { '%', '&', '%' }); //разделяем, тем самым вытаскиваем в массив логин и пароль
                                id = Lreq_To_bd(split[1], split[2]); //передаем в функцию с запросом к БД, логин и пароль
                                if (id != 0)
                                {
                                    byte[] b = Encoding.UTF8.GetBytes("success login="+id); //готовим данные для отправки
                                    connection.Socket.Send(b, b.Length, SocketFlags.None);// отправляем 
                                    Console.WriteLine("Sended. Length = "+b.Length);
                                }
                            }
 
                        }
                        connection.Socket.BeginReceive(
                            connection.Buffer, 0,
                            connection.Buffer.Length, SocketFlags.None,
                            new AsyncCallback(ReceiveCallback),
                            connection);
                    }
                    else CloseConnection(connection);
                }
                catch (SocketException exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Socket exception: " +
                        exc.SocketErrorCode);
                }
                catch (Exception exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Exception: " + exc);
                }
            }
 
            private void CloseConnection(ConnectionInfo ci)
            {
                ci.Socket.Close();
                lock (_connections) _connections.Remove(ci);
            }
 
            public int Lreq_To_bd(string l, string p)
            {
                string request = "select id from logins where login='" + l + "' and pass='" + p + "'"; //создаем запрос к БД
                MySqlConnection myConnection = new MySqlConnection(db_connect);
                MySqlCommand myCommand = new MySqlCommand(request, myConnection);
                myConnection.Open();
                int value = 0;
                try
                {
                    value = int.Parse(myCommand.ExecuteScalar().ToString()); //выполняем запрос и получаем ID
                    Console.WriteLine("done sending req to bd. Value = "+value);
                }
                catch (Exception e) { Console.WriteLine(e.Message); }
                return value;
            }
        }
 
 
            static void Main(string[] args)
            {
                ThreadedServer ts = new ThreadedServer(9390);
 
                ts.Start();
                Console.ReadLine();
 
            }
        }
    }
Скрин консоли сервера и клиента после отправки данных в прикрепленных файлах

p.s. я, конечно, понимаю, что разбираться в этом вам лень, по-этому спасибо всем, кто хотя бы прочитает эту тему =)
0
Миниатюры
Клиент-сервер. Клиент не принимает данные   Клиент-сервер. Клиент не принимает данные  
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.12.2012, 12:29
Ответы с готовыми решениями:

Клиент-сервер: Как определить, что клиент отключился?
Привет. Есть клиент и сервер, при подключении клиента, на сервере создается класс, который содержит...

Клиент-серверное приложение: как определить, что сервер/клиент не отвечает в течении определенного времени
Пишу клиент-серверное приложение. Использую TCPListener и TCPClient. Вопрос: как определить что...

Клиент и сервер
Здравствуйте, помогите пожалуйста!Есть клиент и сервер,которые взаимодействуют между собой.Клиент...

Клиент-сервер
Всем доброго времени суток. У меня возникла следующая проблема. Я не могу отправить текст из...

Клиент-сервер
Доброй ночи ув. программисты. Возникла следующая проблема: есть клиент-серверное приложение для...

4
lawliet93
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
06.12.2012, 17:41  [ТС] 2
Все, я разобрался, просто при новом соединении делалась его копия, и оригинал заносился в коллекцию, так я отправлял данные копии, а нужно было отправлять тому сокету, который в коллекции находится
0
SoLNiFKo
0 / 0 / 0
Регистрация: 05.04.2013
Сообщений: 10
11.04.2013, 09:24 3
ты разбираешься в разработке клиент-серверных программ? не мог бы ты мне помочь?
0
lawliet93
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
11.04.2013, 14:28  [ТС] 4
Цитата Сообщение от SoLNiFKo Посмотреть сообщение
ты разбираешься в разработке клиент-серверных программ? не мог бы ты мне помочь?
могу попробовать помочь ^^
0
Shtefik
1 / 1 / 0
Регистрация: 14.06.2009
Сообщений: 6
27.05.2013, 20:40 5
SoLNiFKo, Добрый день.
В настоящее время я пытаюсь сделать примерно тоже самое и я не очень хорошо разбираюсь в программировании, поясните пожалуйста по подробнее что вы исправили в коде.
0
27.05.2013, 20:40
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.05.2013, 20:40

Клиент - сервер
TCP клиент-сервер. Не получаю ответа от сервера. Сервер прикрепил внизу. Клиент вот: using...

Клиент-сервер
Здравствуйте! Заинтересован в этой теме. В программировании сталкивался с созданием сервера и...

Сервер-клиент
Здравствуйте, посоветуйте пожалуйста книги на тему создания сервер-клиент приложений на C#.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.