iOSソケットプログラミング(入門)
1.CベースBSDソケット(UNIXシステムで共通のネットワークインタフェース)
BSDソケットは最も理解しやすく、入門しやすく、最も柔軟だが最も使いにくいと感じています.特に大規模なプロジェクトでは
ヘッダファイルをインポートする必要があります
サーバ側
クライアント
2.FCSocketインタフェースはBSDソケットより多い
サーバ側とBSDソケットは少し似ていますが、
クライアントはBSDソケットとは全く異なり、入出力ストリームを使用しています.
サーバ側
クライアント
3.CocoaAsyncSocketパッケージCFSocket
TCP、UDP、非同期スレッドの追加、切り離し再接続、TLS/SSLなど、実開発で実現するものを実現しました.
車輪を繰り返す時間がなければ、このようなサードパーティ製のフレームを使うのもいいです.
BSDソケットは最も理解しやすく、入門しやすく、最も柔軟だが最も使いにくいと感じています.特に大規模なプロジェクトでは
ヘッダファイルをインポートする必要があります
#import <sys/socket.h>
#import <netdb.h>
サーバ側
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[4096];
long n;
int i=100;
// socket
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
printf("create socket error: %s(errno: %d)
",strerror(errno),errno);
return;
}
// ip
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8088);//
//
if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
printf("bind socket error: %s(errno: %d)
",strerror(errno),errno);
return;
}
//
if( listen(listenfd, 10) == -1){
printf("listen socket error: %s(errno: %d)
",strerror(errno),errno);
return;
}
//
printf("======waiting for client's request======
");
while(i>0){
if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
n = recv(connfd, buff, MAXLINE, 0);
buff[n] = '\0';
printf("recv msg from client: %s
", buff);
close(connfd);
}
// socket
close(listenfd);
クライアント
-(void)sendDataToServerURL:(NSURL *)url{
int sockfd;
char sendline[4096];
struct sockaddr_in servaddr;
NSString * host = [url host];
// socket
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)
", strerror(errno),errno);
return;
}
// ip
struct hostent * hostEnt = gethostbyname([host UTF8String]);// ip
if (NULL == hostEnt) {
NSLog(@" ");
return;
}
struct in_addr * remoteInAddr = (struct in_addr *)hostEnt->h_addr_list[0];
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8088);
servaddr.sin_addr = *remoteInAddr;
// TCP ( ip )
if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("connect error: %s(errno: %d)
",strerror(errno),errno);
return;
}
// TCP
printf("send msg to server:
");
fgets(sendline, 4096, stdin);
if(send(sockfd, sendline, strlen(sendline), 0) < 0)
{
printf("send msg error: %s(errno: %d)
", strerror(errno), errno);
return;
}
// socket
close(sockfd);
}
2.FCSocketインタフェースはBSDソケットより多い
サーバ側とBSDソケットは少し似ていますが、
クライアントはBSDソケットとは全く異なり、入出力ストリームを使用しています.
サーバ側
//
static void handleConnect(CFSocketRef sock, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
{
NSLog(@" ");
}
-(void)openFCSocket
{
// socket
const CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL};
CFSocketRef cfSocket = CFSocketCreate(
kCFAllocatorDefault,
PF_INET,
SOCK_STREAM,
IPPROTO_TCP,
kCFSocketAcceptCallBack,
(CFSocketCallBack)handleConnect,//
&socketCtxt);
if (cfSocket == NULL) {
NSLog(@" Socket ");
return;
}
// ip
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET; /* Address family */
sin.sin_port = htons(8088); /* Or a specific port */
sin.sin_addr.s_addr= INADDR_ANY;
//
CFDataRef sincfd = CFDataCreate(
kCFAllocatorDefault,
(UInt8 *)&sin,
sizeof(sin));
if (kCFSocketSuccess != CFSocketSetAddress(cfSocket, sincfd)) {
NSLog(@" ");
}
CFRelease(sincfd);
// socket run loop
CFRunLoopSourceRef socketsource = CFSocketCreateRunLoopSource(
kCFAllocatorDefault,
cfSocket,
0);
CFRunLoopAddSource(
CFRunLoopGetCurrent(),
socketsource,
kCFRunLoopDefaultMode);
}
クライアント
NSString *host = @"127.0.0.1";
int port = 8088;
//
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)host,
port, &readStream, &writeStream);
NSInputStream *inputStream = (__bridge NSInputStream *)readStream;
NSOutputStream *outputStream = (__bridge NSOutputStream *)writeStream;
if (inputStream == nil || outputStream == nil) {
NSLog(@" !");
return ;
}
//
[inputStream open];
[outputStream open];
//
NSData *outgoingDataBuffer = [@"testdata" dataUsingEncoding:NSUTF8StringEncoding];
NSInteger writtenBytes = [outputStream write:outgoingDataBuffer.bytes maxLength:outgoingDataBuffer.length];
if ( writtenBytes == -1 ) {
NSLog(@" ");
return;
}
NSLog(@" ");
3.CocoaAsyncSocketパッケージCFSocket
TCP、UDP、非同期スレッドの追加、切り離し再接続、TLS/SSLなど、実開発で実現するものを実現しました.
車輪を繰り返す時間がなければ、このようなサードパーティ製のフレームを使うのもいいです.