Server side: Create a socket with cfsocketcreate (), then set the address with cfsocketsetaddress (), and then use the Cfsocketcreaterunloopsource () Add the socket to the Runloop and use Cfstreamcreatepairwithsocket () in the callback method of the socket to create a Cfreadstreamreff stream bound to the socket. Then convert the cfreadstreamref to Nsinputstream type, set the delegate, add to Runloop, and finally open; in-(void) stream: (nsstream*) Astream Handleevent: (nsstreamevent) The EventCode method handles the Nsstreameventhasbytesavailable event reading the data in the stream. Client side: Create a socket with cfsocketcreate () and connect to the specified address with cfsocketconnecttoaddress (); Add the socket to the Runloop with Cfsocketcreaterunloopsource (), and use the Cfstreamcreatepairwithsocket () in the callback method of the socket. Create a cfwritestreamref stream bound to the socket, then convert the Cfreadstreamref flow to Nsinputstream type, set the delegate, add to Runloop, and finally open; in-(void) Stream: (nsstream*) Astream handleevent: (nsstreamevent) The EventCode method handles the Nsstreameventhasspaceavailable event to write data to the stream. If I skip creating a socket and create a cfwritestreamref stream directly with Cfstreamcreatepairwithsockettohost, there's no problem, why? Please advise the master.
Client:
-(void) Createconnect: (nsstring*) straddress
{
Cfsocketcontext Sockcontext = {0,//version of struct, must be 0
Self
NULL,//A callback that defines the retain in the pointer above, can be null
Null
NULL};
_socket = Cfsocketcreate (Kcfallocatordefault,//allocates memory for new objects, can be nil
Pf_inet,//protocol family, if 0 or negative, the default is Pf_inet
Sock_stream,//socket type, if the protocol family is pf_inet, it defaults to Sock_stream
IPPROTO_TCP,//socket protocol, if the Protocol family is pf_inet and the protocol is 0 or negative, it defaults to IPPROTO_TCP
Kcfsocketconnectcallback,//The type of socket message triggering the callback function, see callback Types
Tcpclientconnectcallback,//callback function triggered in the case above
&sockcontext//An object holding Cfsocket structure information, can be nil
);
if (_socket! = NULL)
{
struct sockaddr_in addr4; IPV4
memset (&ADDR4, 0, sizeof (ADDR4));
Addr4.sin_len = sizeof (ADDR4);
addr4.sin_family = af_inet;
Addr4.sin_port = htons (8888);
ADDR4.SIN_ADDR.S_ADDR = inet_addr ([straddress utf8string]); Converts the address of a string to a machine-readable network address
Convert the address in the SOCKADDR_IN structure to data
Cfdataref address = Cfdatacreate (Kcfallocatordefault, (UInt8 *) &ADDR4, sizeof (ADDR4));
Cfsocketconnecttoaddress (_socket,//socket connected
Address,//Cfdataref object of type containing the remote address of the socket above
-1//Connection timeout time, if negative, do not attempt to connect, but put the connection in the background, if the _socket message type is Kcfsocketconnectcallback, will trigger the callback function in the background when the connection succeeds or fails
);
Cfrunloopref crunref = Cfrunloopgetcurrent (); Gets the loop of the current thread
Create a loop, but not really add to the loop, need to call Cfrunloopaddsource
Cfrunloopsourceref sourceref = Cfsocketcreaterunloopsource (Kcfallocatordefault, _socket, 0);
Cfrunloopaddsource (Crunref,//Run cycle
Sourceref,//increase the running loop source, it will be retain once
Kcfrunloopcommonmodes//Increased mode of running the loop source
);
Cfrelease (SOURCEREF);
NSLog (@ "connect OK");
}
}
Socket callback function, same as Client
static void Tcpclientconnectcallback (Cfsocketref socket, Cfsocketcallbacktype type, cfdataref address, const void *data, void *info)
{
Viewcontroller *client = (Viewcontroller *) info;
if (data! = NULL)
{
NSLog (@ "Connection failed");
[Client. TextView inserttext:@ "Connection failed \ n"];
Return
}
Else
{
NSLog (@ "connected successfully");
[Client. TextView inserttext:@ "Connection succeeded \ n"];
Read the Received data
G_viewpage = client;
[Client Startreadthread];
}
}
-(void) Startreadthread
{
Nsthread *initthread = [[Nsthread alloc]initwithtarget:self selector: @selector (initthreadfunc:) object:self];
[Initthread start];
}
-(void) Initthreadfunc: (ID) sender
{
while (1) {
[Self readstream];
}
}
Read the Received data
-(void) Readstream
{
Char buffer[1024];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *STR = @ "Server sent data:";
Recv (Cfsocketgetnative (_socket), buffer, sizeof (buffer), 0);
{
str = [str stringbyappendingstring:[nsstring stringwithutf8string:buffer]];
}
NSLog (str);
Back Interface Display Information
[Self Performselectoronmainthread: @selector (showmsg:) withobject:str Waituntildone:no];
[Pool release];
}
-(void) ShowMsg: (ID) sender
{
NSString *str = sender;
str = [str stringbyappendingstring:@ "\ n"];
[Self. TextView INSERTTEXT:STR];
}
Send data
-(void) SendMessage {
NSLog (@ "Hello Server");
char *data = "Hello Server";
Send (Cfsocketgetnative (_socket), data, strlen (data) + 1, 0);
}
-(Ibaction) Sendmessagetouch: (ID) Sender {
[Self sendMessage];
}
-(Ibaction) Touchconnectserver: (ID) Sender {
NSString *serverip = Self.textField.text;
[Self createconnect:serverip];
}
-(void) Dealloc {
[_textview release];
[_textfield release];
[Super Dealloc];
}
Cfwritestreamref OutputStream;
Sever:
@implementation Socketserver
-(int) Setupsocket
{
Cfsocketcontext Sockcontext = {0,//version of struct, must be 0
Self
NULL,//A callback that defines the retain in the pointer above, can be null
Null
NULL};
_socket = Cfsocketcreate (Kcfallocatordefault, Pf_inet, Sock_stream, Ipproto_tcp, Kcfsocketacceptcallback, Tcpserveracceptcallback, &sockcontext);
if (NULL = = _socket) {
NSLog (@ "Cannot create socket!");
return 0;
}
int optval = 1;
SetSockOpt (Cfsocketgetnative (_socket), Sol_socket, SO_REUSEADDR,//Allow reuse of local addresses and ports
(void *) &optval, sizeof (optval));
struct sockaddr_in addr4;
memset (&ADDR4, 0, sizeof (ADDR4));
Addr4.sin_len = sizeof (ADDR4);
addr4.sin_family = af_inet;
Addr4.sin_port = htons (8888);
ADDR4.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Cfdataref address = Cfdatacreate (Kcfallocatordefault, (UInt8 *) &ADDR4, sizeof (ADDR4));
if (kcfsocketsuccess! = cfsocketsetaddress (_socket, address))
{
NSLog (@ "Bind to address failed!");
if (_socket)
Cfrelease (_socket);
_socket = NULL;
return 0;
}
Cfrunloopref Cfrunloop = Cfrunloopgetcurrent ();
Cfrunloopsourceref Source = Cfsocketcreaterunloopsource (Kcfallocatordefault, _socket, 0);
Cfrunloopaddsource (Cfrunloop, source, kcfrunloopcommonmodes);
Cfrelease (source);
return 1;
}
-(void) SendMessage
{
char *str = "Hello Client";
uint8_t * uin8b = (uint8_t *) str;
if (outputstream! = NULL)
{
Cfwritestreamwrite (OutputStream, uin8b, strlen (str) + 1);
}
else {
NSLog (@ "Cannot send data!");
}
}
Open up a thread in a thread function
-(void) StartServer
{
int res = [self setupsocket];
if (!res) {
Exit (1);
}
NSLog (@ "Cfrunloop object running current thread");
Cfrunlooprun (); Cfrunloop object running the current thread
}
-(void) Showmsgonmainpage: (nsstring*) STRMSG
{
[Self.delegate showmsg:strmsg];
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
Socket callback function
static void Tcpserveracceptcallback (Cfsocketref socket, Cfsocketcallbacktype type, cfdataref address, const void *data, V OID *info)
{
if (Kcfsocketacceptcallback = = type)
{
Local socket handle
Cfsocketnativehandle nativesockethandle = * (Cfsocketnativehandle *) data;
uint8_t Name[sock_maxaddrlen];
socklen_t Namelen = sizeof (name);
if (0! = Getpeername (Nativesockethandle, (struct sockaddr *) name, &namelen)) {
NSLog (@ "error");
Exit (1);
}
Cfreadstreamref IStream;
Cfwritestreamref OStream;
Create a read-write socket connection
Cfstreamcreatepairwithsocket (Kcfallocatordefault, Nativesockethandle, &istream, &oStream);
if (IStream && oStream)
{
Cfstreamclientcontext Streamcontext = {0, info, null, NULL};
if (! Cfreadstreamsetclient (IStream, Kcfstreameventhasbytesavailable,readstream, &streamcontext))
{
Exit (1);
}
if (! Cfwritestreamsetclient (OStream, Kcfstreameventcanacceptbytes, Writestream, &streamcontext))
{
Exit (1);
}
Cfreadstreamschedulewithrunloop (IStream, Cfrunloopgetcurrent (), Kcfrunloopdefaultmode);
Cfwritestreamschedulewithrunloop (OStream, Cfrunloopgetcurrent (), Kcfrunloopdefaultmode);
Cfreadstreamopen (IStream);
Cfwritestreamopen (OStream);
} else
{
Close (Nativesockethandle);
}
}
}
Reading data
void Readstream (Cfreadstreamref stream, Cfstreameventtype eventtype, void *clientcallbackinfo)
{
UInt8 buff[255];
Cfreadstreamread (stream, buff, 255);
According to delegate display to the main interface to go
NSString *strmsg = [[NSString alloc]initwithformat:@ "client message:%s", Buff];
Socketserver *info = (socketserver*) clientcallbackinfo;
[Info showmsgonmainpage:strmsg];
}
void Writestream (Cfwritestreamref stream, Cfstreameventtype eventtype, void *clientcallbackinfo)
{
OutputStream = stream;
}
iOS socket sockets Programming (GO)