gpt4 book ai didi

objective-c - 在 Objective-C 中使用 CFSocket 创建套接字时出现问题(iPhone 应用程序)

转载 作者:太空狗 更新时间:2023-10-30 03:33:18 25 4
gpt4 key购买 nike

好的,我在使用 Objective-C 构建套接字时遇到了问题。如果您在下面查看我的代码,通过示例代码和其他资源的帮助,我相信我能够构建一个完整的套接字。问题是当我编译它时,它构建良好(没有语法问题),但没有创建套接字。正如您将注意到的,我在 Server2.m 中注释掉了很多内容,并且在我为 listeningSocket 创建结构时将问题隔离到最开始。顺便说一句,如果这有帮助,它是服务器-客户端应用程序的服务器端的一部分。有谁知道为什么我会遇到这个问题?昨天一切似乎都运行良好,今天早上我想我会采用不同的方法来构建套接字,所以我尝试了这个。感谢您的帮助!

Server_TrialViewController.m

#include <CFNetwork/CFSocketStream.h>
#import <UIKit/UIKit.h>
#import "Server2.h"
#import "Client_Test.h"

@interface Server_TrialViewController : UIViewController {
IBOutlet UIButton *ServerButton;
IBOutlet UIButton *ClientButton;
IBOutlet UILabel *statusLabel;
Server2 *server;
Client_Test *client;
}

@property(nonatomic, retain) UILabel *statusLabel;
@property(nonatomic, retain) Server2 *server;
@property(nonatomic, retain) Client_Test *client;

-(IBAction)serverButtonPressed;
-(IBAction)clientButtonPressed;
//-(void)sendMessageWithServer:(Server_Test *)SERVER AndClient:(Client_Test *)CLIENT;

@end

Server_TrialViewController.h

#import "Server_TrialViewController.h"

@implementation Server_TrialViewController
@synthesize statusLabel;
@synthesize server;
@synthesize client;

-(IBAction)serverButtonPressed {
if ([server start]) {
[statusLabel setText:@"Success"];
}
else {
if (server.status == NULL) {
[statusLabel setText: @"No Server: No statUpdate"];
}
else {
[statusLabel setText: @"No Server: Found statUpdate"];
}
}
}


-(IBAction)clientButtonPressed {
if ([client start]) {
[statusLabel setText:@"Client Started"];
}
else {
[statusLabel setText:@"Client Not Started"];
}
}


- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}


- (void)dealloc {
[super dealloc];
}

@end

Server2.h

#import <Foundation/Foundation.h>
#import "Server2Delegate.h"

@interface Server2 : NSObject
{
uint16_t port;
CFSocketRef listeningSocket;
id<Server2Delegate> delegate;
NSNetService* netService;
NSString *status;
}

// Initialize connection
- (BOOL)start;
- (void)stop;

// Delegate receives various notifications about the state of our server
@property(nonatomic,retain) id<Server2Delegate> delegate;
@property(nonatomic, retain) NSString *status;

@end

Server2.m

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <CFNetwork/CFSocketStream.h>

#import "Server2.h"
#import "Connection2.h"
#import "AppConfig2.h"

// Declare some private properties and methods
@interface Server2 ()
@property(nonatomic,assign) uint16_t port;
@property(nonatomic,retain) NSNetService* netService;

-(BOOL)createServer;
-(void)terminateServer;

@end

// Implementation of the Server interface
@implementation Server2

@synthesize delegate;
@synthesize port, netService;
@synthesize status;

// Cleanup
- (void)dealloc
{
self.netService = nil;
self.delegate = nil;
[super dealloc];
}


// Create server and announce it
- (BOOL)start
{
// Start the socket server
if ( ! [self createServer] )
{
status = @"Server Not Created";
return FALSE;
}
status = @"Server Created";
return TRUE;
}


// Close everything
- (void)stop {
[self terminateServer];
}

#pragma mark Callbacks

// Handle new connections
- (void)handleNewNativeSocket:(CFSocketNativeHandle)nativeSocketHandle {
Connection2* connection = [[[Connection2 alloc] initWithNativeSocketHandle:nativeSocketHandle] autorelease];

// In case of errors, close native socket handle
if ( connection == nil ) {
close(nativeSocketHandle);
return;
}

// finish connecting
if ( ! [connection connect] ) {
//status = @"Connection Not Made";
[connection close];
return;
}

//status = @"Connection Made";

// Pass this on to our delegate
[delegate handleNewConnection:connection];
}


// This function will be used as a callback while creating our listening socket via 'CFSocketCreate'
static void serverAcceptCallback(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
Server2 *server = (Server2*)info;

// We can only process "connection accepted" calls here
if ( type != kCFSocketAcceptCallBack ) {
return;
}

// for an AcceptCallBack, the data parameter is a pointer to a CFSocketNativeHandle
CFSocketNativeHandle nativeSocketHandle = *(CFSocketNativeHandle*)data;

[server handleNewNativeSocket:nativeSocketHandle];
}


#pragma mark Sockets and streams

- (BOOL)createServer
{
//// PART 1: Create a socket that can accept connections

// Socket context
// struct CFSocketContext {
// CFIndex version;
// void *info;
// CFAllocatorRetainCallBack retain;
// CFAllocatorReleaseCallBack release;
// CFAllocatorCopyDescriptionCallBack copyDescription;
// };
CFSocketContext socketContext = {0, self, NULL, NULL, NULL};

listeningSocket = CFSocketCreate(
kCFAllocatorDefault,
PF_INET, // The protocol family for the socket
SOCK_DGRAM, // The socket type to create
IPPROTO_UDP, // The protocol for the socket. TCP vs UDP.
0, //kCFSocketAcceptCallBack, // New connections will be automatically accepted and the callback is called with the data argument being a pointer to a CFSocketNativeHandle of the child socket.
NULL, //(CFSocketCallBack)&serverAcceptCallback,
&socketContext );

// Previous call might have failed
if ( listeningSocket == NULL ) {
status = @"listeningSocket Not Created";
return FALSE;
}
else {
status = @"listeningSocket Created";
return TRUE;
}
}
/*
// getsockopt will return existing socket option value via this variable
int existingValue = 1;

// Make sure that same listening socket address gets reused after every connection
setsockopt( CFSocketGetNative(listeningSocket),
SOL_SOCKET, SO_REUSEADDR, (void *)&existingValue,
sizeof(existingValue));


//// PART 2: Bind our socket to an endpoint.
// We will be listening on all available interfaces/addresses.
// Port will be assigned automatically by kernel.
struct sockaddr_in socketAddress;
memset(&socketAddress, 0, sizeof(socketAddress));
socketAddress.sin_len = sizeof(socketAddress);
socketAddress.sin_family = AF_INET; // Address family (IPv4 vs IPv6)
socketAddress.sin_port = 0; // Actual port will get assigned automatically by kernel
socketAddress.sin_addr.s_addr = htonl(INADDR_ANY); // We must use "network byte order" format (big-endian) for the value here

// Convert the endpoint data structure into something that CFSocket can use
NSData *socketAddressData =
[NSData dataWithBytes:&socketAddress length:sizeof(socketAddress)];

// Bind our socket to the endpoint. Check if successful.
if ( CFSocketSetAddress(listeningSocket, (CFDataRef)socketAddressData) != kCFSocketSuccess ) {
// Cleanup
if ( listeningSocket != NULL ) {
status = @"Socket Not Binded";
CFRelease(listeningSocket);
listeningSocket = NULL;
}

return FALSE;
}
status = @"Socket Binded";

//// PART 3: Find out what port kernel assigned to our socket
// We need it to advertise our service via Bonjour
NSData *socketAddressActualData = [(NSData *)CFSocketCopyAddress(listeningSocket) autorelease];

// Convert socket data into a usable structure
struct sockaddr_in socketAddressActual;
memcpy(&socketAddressActual, [socketAddressActualData bytes],
[socketAddressActualData length]);

self.port = ntohs(socketAddressActual.sin_port);

//// PART 4: Hook up our socket to the current run loop
CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent();
CFRunLoopSourceRef runLoopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, listeningSocket, 0);
CFRunLoopAddSource(currentRunLoop, runLoopSource, kCFRunLoopCommonModes);
CFRelease(runLoopSource);

return TRUE;
}
*/

- (void) terminateServer {
if ( listeningSocket != nil ) {
CFSocketInvalidate(listeningSocket);
CFRelease(listeningSocket);
listeningSocket = nil;
}
}


#pragma mark -
#pragma mark NSNetService Delegate Method Implementations

// Delegate method, called by NSNetService in case service publishing fails for whatever reason
- (void)netService:(NSNetService*)sender didNotPublish:(NSDictionary*)errorDict {
if ( sender != self.netService ) {
return;
}

// Stop socket server
[self terminateServer];
}

@end

最佳答案

对于寻找有关 CFSocket 服务器信息的人来说,答案如下:如果将“SOCK_DGRAM”更改为“SOCK_STREAM”,上面的代码可以正常工作。

关于objective-c - 在 Objective-C 中使用 CFSocket 创建套接字时出现问题(iPhone 应用程序),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1040542/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com