先來講述下我自己對于整個Socket通信過程的理解,畢竟初學,說錯見諒,知道錯了會改正~
首先在服務端新建一個serverSocket,對其進行初始化(一般包含AddressFamily:IP地址類型,SocketType:Socket傳輸數據方式,ProtoType:傳輸協議);
接著我們要設置server端要綁定的IP:port;然后開始監聽,并設置最多同時監聽多少個Client.
這時,服務端就在等待狀態,直到某一個Client連接到這個ip:port上,這時serverSocket.Accept()工作,獲得這個連接。(此時的連接是有地址信息的哦!記得保存)
獲得連接之后,server就可以和這個Client進行通信了,當加入第二個Client(我們稱其為ClientB)時,Server接收到ClientB的消息,可以將這個消息轉發給前一個Client(我們稱其為ClientA),當受到ClientA的消息,也可以轉發給ClientB。這樣就實現了Clients之間的通信了。(重點在保存連接信息!?。?/p>
那么現在貼上代碼講解:
Server端代碼
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
|
namespace SocketServer { class Program { private static byte [] result = new byte [1024]; static Socket serverSocket; private static string client; private static Socket clientSocket; //我這里存了兩個Client,因為自己電腦開了兩個Client,不會有多的 //理論上應該開一個Socket[]來保存信息,最好用一個二元組將client的信息和連接綁定起來 //這樣就可以實現斷開連接后下次登陸還是可以識別是這個Client private static Socket clientSocketA= null ; private static Socket clientSocketB= null ; static void Main( string [] args) { Program.SetPort(8885); } private static void SetPort( int port) { IPAddress ip = IPAddress.Parse( "127.0.0.1" ); //set ip serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //initialize serverSocket.Bind( new IPEndPoint(ip, port)); //bind serverSocket.Listen(10); //進入監聽狀態 Console.WriteLine( "監聽{0}成功" , serverSocket.LocalEndPoint.ToString()); //開啟一個線程來監聽客戶端連接 Thread myThread = new Thread(ListenClientConnect); myThread.Start(); Console.ReadLine(); } /// <summary> /// 監聽客戶端連接 /// </summary> private static void ListenClientConnect() { while ( true ) { //Client連接上后 得到這個連接 clientSocket = serverSocket.Accept(); //這里我因為只有兩個Client,所以就簡單寫了 if (clientSocketA == null ) { clientSocketA = clientSocket; } else if (clientSocketB == null ) { clientSocketB = clientSocket; } else { //當其中一個斷開了,又重新連接時,需要再次保存連接 if (clientSocketB.IsBound) { clientSocketA = clientSocketB; clientSocketB = clientSocket; } else { clientSocketB = clientSocketA; clientSocketA = clientSocket; } } clientSocket.Send(Encoding.ASCII.GetBytes( "say hello" )); //開個線程接收Client信息 Thread receivedThread = new Thread(ReceiveMessage); receivedThread.Start(clientSocket); } } private static void ReceiveMessage( object clientSocket) { Socket myClientSocket = (Socket) clientSocket; while ( true ) { try { int revceiveNumber = myClientSocket.Receive(result); //Console.WriteLine("接受客戶端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString() // , Encoding.ASCII.GetString(result, 0, revceiveNumber)); Console.WriteLine(Encoding.ASCII.GetString(result, 0, revceiveNumber)); if (myClientSocket == clientSocketA) { Console.WriteLine( "receive from A" ); if (clientSocketB!= null &&clientSocketB.IsBound) { Console.WriteLine( "a IS BOUND" ); clientSocketB.Send(result, 0, revceiveNumber, SocketFlags.None); } else { myClientSocket.Send(Encoding.ASCII.GetBytes( "the people is not online! Send Failed!" )); Console.WriteLine( "對方不在線上,發送失敗!" ); } } else { Console.WriteLine( "receive from B" ); if (clientSocketA != null && clientSocketA.IsBound) { Console.WriteLine( "a IS BOUND" ); clientSocketA.Send(result, 0, revceiveNumber, SocketFlags.None); } else { myClientSocket.Send(Encoding.ASCII.GetBytes( "the people is not online! Send Failed!" )); Console.WriteLine( "對方不在線上,發送失敗!" ); } } } catch (Exception ex) { Console.WriteLine(ex.Message); myClientSocket.Shutdown(SocketShutdown.Both); myClientSocket.Close(); break ; } } } } } |
Client端代碼(因為都差不多 就只貼一個了)
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
|
namespace SocketClient { class Program { private static byte [] result = new byte [1024]; private static Socket clientSocket; private static void ListenServer() { while ( true ) { result = new byte [1024]; int receiveLength = clientSocket.Receive(result); Console.WriteLine( "{0}" , Encoding.ASCII.GetString(result, 0, receiveLength)); } } static void Main( string [] args) { IPAddress ip = IPAddress.Parse( "127.0.0.1" ); clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { clientSocket.Connect(ip, 8885); Console.WriteLine( "連接成功!" ); } catch (Exception e) { Console.WriteLine( "連接失??!" ); return ; } Thread threadRead = new Thread(ListenServer); threadRead.Start(); while ( true ) { try { Thread.Sleep(1000); string sendMessage = Console.ReadLine(); clientSocket.Send(Encoding.ASCII.GetBytes( "Sylvia:" +sendMessage)); } catch (Exception ex) { clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); break ; } } Console.WriteLine( "發送完畢 按回車退出" ); Console.ReadKey(); } } } |
寫的時候要特別注意一下Send信息的時候,注意byte[]的傳輸大小,很容易變成byte[]數組的大小而不是內容的大小。
這個大家就自己嘗試吧。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。