紧接着上一篇文章,贴出我的代码
#import <Foundation/Foundation.h>
@interface NSStream (MyAdditions)
+ (void)getStreamsToHostNamed:(NSString *)hostName port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr;
@end
#import "NSStreamAdditions.h"
@implementation NSStream (MyAdditions)
//使用TCP协议连接到服务器。
+ (void)getStreamsToHostNamed:(NSString *)hostName port:(NSInteger)port
inputStream:(NSInputStream **)inputStreamPtr
outputStream:(NSOutputStream **)outputStreamPtr{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
assert(hostName != nil);
assert( (port > 0) && (port < 65536) );
assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
readStream = NULL;
writeStream = NULL;
CFStreamCreatePairWithSocketToHost(
NULL,
(CFStringRef) hostName,
port,
((inputStreamPtr != nil) ? &readStream : NULL),
((outputStreamPtr != nil) ? &writeStream : NULL)
);
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
}
@end
#import <UIKit/UIKit.h>
#import "NSStreamAdditions.h"
@interface testVoiceChatViewController : UIViewController
<NSStreamDelegate>{
NSMutableData *data;
NSInputStream *iStream;
NSOutputStream *oStream;
}
-(IBAction)Send;
@end
#import "testVoiceChatViewController.h"
@interface testVoiceChatViewController()
-(void) connectToServerUsingStream:(NSString *)urlStr
portNo: (uint) portNo;
-(void) connectToServerUsingCFStream:(NSString *) urlStr
portNo: (uint) portNo;
-(void) writeToServer:(const uint8_t *) buf;
-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode;
@end
@implementation testVoiceChatViewController
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
- (void)viewDidLoad {
[super viewDidLoad];
[self connectToServerUsingStream:@"192.168.1.90" portNo:500];
//---OR---
//[self connectToServerUsingCFStream:@"192.168.1.102" portNo:500];
}
-(void) connectToServerUsingStream:(NSString *)urlStr
portNo: (uint) portNo {
if (![urlStr isEqualToString:@""]) {
NSURL *website = [NSURL URLWithString:urlStr];
if (!website) {
NSLog(@"%@ is not a valid URL");
return;
}
else {
[NSStream getStreamsToHostNamed:urlStr
port:portNo
inputStream:&iStream
outputStream:&oStream];
[iStream retain];
[oStream retain];
[iStream setDelegate:self];
[oStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream open];
[iStream open];
}
}
}
/*
使用CFStreamCreatePairWithSocketToHost()方法创建一个可读写的流,
通过TCP/IP连接到服务器,这个方法返回这个可读写流(readStream和writeStream)的引用,
它们和Objective C中的NSInputStream和NSOutputStream是等效的
*/
-(void) connectToServerUsingCFStream:(NSString *) urlStr
portNo: (uint) portNo {
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(CFStringRef) urlStr,
portNo,
&readStream,
&writeStream);
if (readStream && writeStream) {
CFReadStreamSetProperty(readStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
CFWriteStreamSetProperty(writeStream,
kCFStreamPropertyShouldCloseNativeSocket,
kCFBooleanTrue);
iStream = (NSInputStream *)readStream;
[iStream retain];
[iStream setDelegate:self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[iStream open];
oStream = (NSOutputStream *)writeStream;
[oStream retain];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[oStream open];
}
}
//使用NSOutputStream对象向服务器发送数据
//这个方法向服务器发送一组无符号整数字节。
-(void) writeToServer:(const uint8_t *) buf {
[oStream write:buf maxLength:strlen((char *)buf)];
}
/*
这个方法包括两个参数:一个是NSStream实例,一个是NSStreamEvent常量,
NSStreamEvent常量可以是以下的值:
NSStreamEventNone:无事件发生。
NSStreamEventOpenCompleted:打开事件已经成功完成。
NSStreamEventHasBytesAvailable:已经读取的流字节数。
NSStreamEventHasSpaceAvailable:流接收的可写入的字节数。
NSStreamEventErrorOccurred:在流上发生了错误。
NSStreamEventEndEncountered:已经抵达流的结尾。
读取入站数据时,你应该检查NSStreamEventHasBytesAvailable常量,
在这个方法中,你可以读取入站数据流,然后UIAlertView对象显示接收到的数据。
stream:handleEvent:方法也是检查连接错误的一个好方法,
例如,如果connectToServerUsingStream:portNo:方法连接到服务器时失败了,
错误将使用stream:handleEvent:方法通知,
NSStreamEvent常量设置为NSStreamEventErrorOccurred。
*/
-(IBAction)Send{
NSString *string = @"hello";
const uint8_t *str = (uint8_t *) [string
cStringUsingEncoding:NSASCIIStringEncoding];
[self writeToServer:str];
}
-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
switch(eventCode) {
case NSStreamEventHasBytesAvailable:
{
if (data == nil) {
data = [[NSMutableData alloc] init];
}
uint8_t buf[1024];
unsigned int len = 0;
len = [(NSInputStream *)stream read:buf maxLength:1024];
if(len) {
[data appendBytes:(const void *)buf length:len];
int bytesRead;
bytesRead += len;
} else {
NSLog(@"No data.");
}
NSString *str = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"str :%@",str);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"From server"
message:str
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
[str release];
[data release];
data = nil;
}
break;
}
}
//断开连接
-(void) disconnect {
[iStream close];
[oStream close];
}
- (void)dealloc {
[self disconnect];
[iStream close];
[oStream close];
if (readStream) {
CFRelease(readStream);
}
if (writeStream) {
CFRelease(writeStream);
}
[super dealloc];
}
服务器
using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Net.Sockets;
5 namespace Server_CS
6 {
7 class Program
8 {
9 const int portNo = 500;
10 static void Main(string[] args)
11 {
12 System.Net.IPAddress localAdd =
13 System.Net.IPAddress.Parse("192.168.1.90");
14 TcpListener listener = new TcpListener(localAdd, portNo);
15 listener.Start();
16 while (true)
17 {
18 TcpClient tcpClient = listener.AcceptTcpClient();
19 NetworkStream ns = tcpClient.GetStream();
20 byte[] data = new byte[tcpClient.ReceiveBufferSize];
21 int numBytesRead = ns.Read(data, 0,
22 System.Convert.ToInt32(tcpClient.ReceiveBufferSize));
23 Console.WriteLine("Received :" +
24 Encoding.ASCII.GetString(data, 0, numBytesRead));
25 //---write back to the client---
26 ns.Write(data, 0, numBytesRead);
27 }
28 }
29 }
30 }