i'm a beginner in network programming and i have a project in which i have to create a system explorer. That means that i will have the ability to write a http request with a directory in a browser and if the connection with the server is succesfull, the files from the above directory will open.
int main(int argc, char** argv)
{
typedef struct tcpip_connection
{
int connfd;
struct sockaddr_in peer_addr;
} tcpip_connection;
int s_socket, *fd, port;
char buffer[256];
struct sockaddr_in lis_addr;
struct sockaddr_in peer_addr;
int sopt = 1, n;
s_socket=socket(AF_INET, SOCK_STREAM, 0);
if(s_socket<0){
printf("error: the socket was not created!");
}
if(setsockopt(s_socket , SOL_SOCKET, SO_REUSEADDR, &sopt, sizeof(sopt))){
printf("Setsokopt error!");
}
memset(&lis_addr, 0, sizeof(lis_addr));
lis_addr.sin_family = AF_INET;
lis_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lis_addr.sin_port = htons(port);
if ( bind( s_socket, (struct sockaddr*) &lis_addr, sizeof(lis_addr) ) < 0 ){
perror(NULL);
exit(-1);
}
if(listen(s_socket,15)<0){
perror("server.listen");
}
socklen_t peer_addrlen;
while(1){
if((fd = malloc(sizeof(int))) == NULL){
fprintf(stderr, "Out of memory\n");
abort();
}
*fd=accept(s_socket, (struct sockaddr*)&peer_addr,&peer_addrlen);
if(fd<0){
if( errno==EINTR /* Call interrupted by signal */
|| errno==ECONNABORTED /* connection was aborted */
|| errno==EMFILE /* per-process limit of open fds */
|| errno==ENFILE /* system-wide limit of open fds */
|| errno==ENOBUFS /* no space for socket buffers */
|| errno==ENOMEM /* no space for socket buffers */
|| errno==EPERM /* Firewall blocked the connection */
)
continue;
}
}
if(errno == EBADF)
break; /* return, the server_socket is closed */
}
bzero(buffer,1024);
n = read(*fd,buffer,1023);
if (n < 0)
{
perror("ERROR reading from socket");
exit(1);
}
printf("Here is the message: %s\n",buffer);
/* Write a response to the client
n = write(*fd,"I got your message",18);
if (n < 0)
{
perror("ERROR writing to socket");
exit(1);
}
return 0;*/
}
I don't know if there is anything wrong with my code, but the main problem is that i don't know how to make the browser connect with the server. Is there anything i have to write in the browser or do i have to add some extra code?
You forgot to initialize the port variable. Try setting port = 8080 before you call bind and listen.
Then, in your browser, go to http://localhost:8080/ and it should connect.
Related
Let me start by saying this is my first foray into the world of C after 20+ years of assembly programming for PLCs and MicroControllers.
I'm trying to send a UDP datagram to the network broadcast address, in this particular case, 192.168.1.255.
The error I'm getting is a bind failure with error code 10049 (from WSAGetLastError()). As you can see from the attached code, I've created the socket, populated sockaddr_in, and setsockopt() to SO_BROADCAST.
For the life of me I can't figure out what I'm doing wrong and any pointers would be gratefully received.
iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
WSAErrorString("WSAStartup for TX failed");
return(-1);
}
XPLMDebugString("UDP Server: WSAStartup TX complete.\n");
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
WSAErrorString("UDP Server: Could not create BECN socket");
return(-1);
}
// setup the sockaddr_in structure
//
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
si_beacon.sin_port = htons(_UDP_TX_PORT);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
WSAErrorString("Error in setting Broadcast option");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr *)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
WSAErrorString("Bind to socket for UDP beacon failed");
sprintf(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
XPLMDebugString(buf);
return(-1);
}
// start the UDP beacon
//
udp_becn_thread_id = CreateThread(NULL, 0, BeaconThread, NULL, 0, NULL);
if (!udp_becn_thread_id) {
WSAErrorString("UDP Server: Error starting UDP Beacon");
return (-1);
}
XPLMDebugString("UDP Server: bind complete. beacon ACTIVE.\n");
return(0);
The issue is the IP address itself.
I copied the code to my computer (changed it a bit to get it to compile) and I got the error:
UDP Server: WSAStartup TX complete.
Bind to socket for UDP beacon failed
Port 47977, address 192.168.1.255
I then changed the line:
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
To
si_beacon.sin_addr.s_addr = inet_addr("192.168.0.127");
And when I ran it again, everything worked:
UDP Server: WSAStartup TX complete.
Done successfully
The issue is that the "bind" address needs to be your computers address on the local network. Not the remote client.
Another alternative is to use the address:
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
which binds to all network interfaces on the computer at once.
For reference, here's the version of the code that I used:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h> // For inet_pton
#pragma comment(lib, "ws2_32.lib")
int main()
{
{
WSADATA wsaTxData;
memset(&wsaTxData, 0, sizeof(WSADATA));
const int iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
printf("%s", "WSAStartup for TX failed.\n");
return -1;
}
printf("%s", "UDP Server: WSAStartup TX complete.\n");
}
SOCKET BeaconSocket;
memset(&BeaconSocket, 0, sizeof(SOCKET));
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
printf("%s", "UDP Server: Could not create BECN socket\n");
return -1;
}
// setup the sockaddr_in structure
//
sockaddr_in si_beacon;
memset(&si_beacon, 0, sizeof(sockaddr_in));
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
const unsigned short port_num = 0xbb69;
si_beacon.sin_port = htons(port_num);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
printf("%s", "Error in setting Broadcast option\n");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr*)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
printf("%s", "Bind to socket for UDP beacon failed\n");
sprintf_s(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
printf("%s", buf);
return(-1);
}
printf("%s", "Done successfully");
return 0;
}
I have a small C program where I am trying to bind to a socket at a certain ip:port. Here it the program -
int main ()
{
int udp_fd = -1;
struct sockaddr_in sockaddr;
char *ip = (char *)"xx.yyy.zzz.aaa";
int port = 1234;
udp_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_fd == -1) {
printf("Could not create socket\n");
return -1;
}
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = inet_addr(ip);
sockaddr.sin_port = htons(port);
if (bind(udp_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == -1) {
printf("Could not bind to %s: %d: %d: %d\n", ip, port, errno, udp_fd);
return -1;
}
if (fcntl(udp_fd, F_SETFL, O_NONBLOCK | O_ASYNC) < 0) {
printf("Error setting socket as non-blocking \n");
return -1;
}
return 0;
}
This fails with EADDRNOTAVAIL
define EADDRNOTAVAIL 99 /* Cannot assign requested address */
I try to connect to the same server from another device that is on the same network as the other device that fails the bind and it is successful.
There are no firewalls enabled on the failing device.
You are trying to bind your socket to a non-local IP address.
You don't generally need to bind to a specific IP address at all. Change:
sockaddr.sin_addr.s_addr = inet_addr(ip);
to
sockaddr.sin_addr.s_addr = INADDR_ANY;
I am using Microsoft Visual Studio 2010 and wolfSSL 3.7.0.
I create server context with these functions:
WOLFSSL_CTX *sslContext = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
if(!sslContext)
{
closesocket(socketListen);
return FALSE;
}
wolfSSL_CTX_use_certificate_buffer(sslContext, (unsigned char*)szServerCert, strlen(szServerCert), SSL_FILETYPE_PEM);
wolfSSL_CTX_use_PrivateKey_buffer(sslContext, (unsigned char*)szServerKey, strlen(szServerKey), SSL_FILETYPE_PEM);
It is OK. Then, I accept the connection, create WOLFSSL* context and associate it with my socket descriptor:
WOLFSSL *ssl = wolfSSL_new(sslContext);
wolfSSL_set_fd(ssl, Socket);
CHAR Buffer[1024];
int retVal = wolfSSL_read(ssl, Buffer, 1024);
But when I try to connect to 127.0.0.1:443 via browser, wolfSSL_read() returns 0. wolfSSL_get_error() returns -397 (SOCKET_PEER_CLOSED_E). Browser shows me that page is still loading. What is the reason?
wolfSSL provides a good reference example here: https://github.com/wolfSSL/wolfssl-examples/blob/master/tls/server-tls.c
Please find referenced code below:
/* server-tls.c
*
* Copyright (C) 2006-2015 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*=============================================================================
*
* This is a super basic example of what a TCP Server secured with TLS 1.2
* might look like. This server can also resume the session if a client
* inadvertantly disconnects.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
/* include the wolfSSL library for our TLS 1.2 security */
#include <wolfssl/ssl.h>
#define DEFAULT_PORT 11111
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr);
int AcceptAndRead(WOLFSSL_CTX* ctx, socklen_t sockfd, struct sockaddr_in
clientAddr)
{
/* Create our reply message */
const char reply[] = "I hear ya fa shizzle!\n";
socklen_t size = sizeof(clientAddr);
/* Wait until a client connects */
socklen_t connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size);
/* If fails to connect,int loop back up and wait for a new connection */
if (connd == -1) {
printf("failed to accept the connection..\n");
}
/* If it connects, read in and reply to the client */
else {
printf("Client connected successfully\n");
WOLFSSL* ssl;
if ( (ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "wolfSSL_new error.\n");
exit(EXIT_FAILURE);
}
/* direct our ssl to our clients connection */
wolfSSL_set_fd(ssl, connd);
printf("Using Non-Blocking I/O: %d\n", wolfSSL_get_using_nonblock(
ssl));
for ( ; ; ) {
char buff[256];
int ret = 0;
/* Clear the buffer memory for anything possibly left over */
memset(&buff, 0, sizeof(buff));
/* Read the client data into our buff array */
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) {
/* Print any data the client sends to the console */
printf("Client: %s\n", buff);
/* Reply back to the client */
if ((ret = wolfSSL_write(ssl, reply, sizeof(reply)-1))
< 0)
{
printf("wolfSSL_write error = %d\n", wolfSSL_get_error(ssl, ret));
}
}
/* if the client disconnects break the loop */
else {
if (ret < 0)
printf("wolfSSL_read error = %d\n", wolfSSL_get_error(ssl
,ret));
else if (ret == 0)
printf("The client has closed the connection.\n");
break;
}
}
wolfSSL_free(ssl); /* Free the WOLFSSL object */
}
close(connd); /* close the connected socket */
return 0;
}
int main()
{
/* Create a ctx pointer for our ssl */
WOLFSSL_CTX* ctx;
/*
* Creates a socket that uses an internet IP address,
* Sets the type to be Stream based (TCP),
* 0 means choose the default protocol.
*/
socklen_t sockfd = socket(AF_INET, SOCK_STREAM, 0);
int loopExit = 0; /* 0 = False, 1 = True */
int ret = 0; /* Return value */
/* Server and client socket address structures */
struct sockaddr_in serverAddr = {0}, clientAddr = {0};
/* Initialize wolfSSL */
wolfSSL_Init();
/* If positive value, the socket is valid */
if (sockfd == -1) {
printf("ERROR: failed to create the socket\n");
return EXIT_FAILURE; /* Kill the server with exit status 1 */
}
/* create and initialize WOLFSSL_CTX structure */
if ((ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method())) == NULL) {
fprintf(stderr, "wolfSSL_CTX_new error.\n");
return EXIT_FAILURE;
}
/* Load server certificate into WOLFSSL_CTX */
if (wolfSSL_CTX_use_certificate_file(ctx, "../certs/server-cert.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-cert.pem, please check"
"the file.\n");
return EXIT_FAILURE;
}
/* Load server key into WOLFSSL_CTX */
if (wolfSSL_CTX_use_PrivateKey_file(ctx, "../certs/server-key.pem",
SSL_FILETYPE_PEM) != SSL_SUCCESS) {
fprintf(stderr, "Error loading certs/server-key.pem, please check"
"the file.\n");
return EXIT_FAILURE;
}
/* load DH params */
ret = wolfSSL_CTX_SetTmpDH_file(ctx, "../certs/dh2048.pem" , SSL_FILETYPE_PEM);
if (ret != SSL_SUCCESS) {
fprintf(stderr, "Error setting DH parameters.\n");
return EXIT_FAILURE;
}
/* Initialize the server address struct to zero */
memset((char *)&serverAddr, 0, sizeof(serverAddr));
/* Fill the server's address family */
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(DEFAULT_PORT);
/* Attach the server socket to our port */
if (bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr))
< 0) {
printf("ERROR: failed to bind\n");
return EXIT_FAILURE;
}
printf("Waiting for a connection...\n");
/* Continuously accept connects while not currently in an active connection
or told to quit */
while (loopExit == 0) {
/* listen for a new connection, allow 5 pending connections */
ret = listen(sockfd, 5);
if (ret == 0) {
/* Accept client connections and read from them */
loopExit = AcceptAndRead(ctx, sockfd, clientAddr);
}
}
wolfSSL_CTX_free(ctx); /* Free WOLFSSL_CTX */
wolfSSL_Cleanup(); /* Free wolfSSL */
return EXIT_SUCCESS;
}
I would like to search Sat>IP servers on the network. Sat>IP servers advertise their presence to other Sat>IP servers and clients.
I must not continuosly send M-SEARCH messages but that instead it listens to server NOTIFY messages.
After initalizing network settings of my device, I'm sending M-SEARCH message and getting response if there is already any active Sat>IP server.
However, I couldn't get any response, If I opens Sat>IP server after sending M-SEARCH message.
Here's my code.
void SatIP::InitDiscoverThread()
{
if(INVALID_THREAD_CHK == DiscoverThreadChk)
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, PTHREAD_STACK_SIZE);
printf("InitDiscoverThread pthread_create\n");
DiscoverThreadChk = PTH_RET_CHK(pthread_create(&DiscoverThreadID, &attr, DiscoverThreadFunc, this));
if(DiscoverThreadChk != 0)
{
ASSERT(0);
}
}
}
void SatIP::FinalizeDiscoverThread()
{
if(INVALID_THREAD_CHK != DiscoverThreadChk)
{
printf("FinalizeDiscoverThread pthread_cancel\n");
pthread_cancel(DiscoverThreadID);
DiscoverThreadChk = INVALID_THREAD_CHK;
close(discoverSocket);
}
}
void *SatIP::DiscoverThreadFunc(void* arg)
{
SatIP* satip = (SatIP *)arg;
satip->ListenSSDPResponse();
pthread_exit(NULL);
}
bool SatIP::SendMSearchMessage()
{
vSatIPServers.clear();
FinalizeDiscoverThread();
const char *searchSatIPDevice = "M-SEARCH * HTTP/1.1\r\n" \
"HOST: 239.255.255.250:1900\r\n" \
"MAN: \"ssdp:discover\"\r\n" \
"MX: 2\r\n" \
"ST: urn:ses-com:device:SatIPServer:1\r\n\r\n";
struct sockaddr_in upnpControl, broadcast_addr;
discoverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (discoverSocket == INVALID_SOCKET)
{
printf("socked failed INVALID_SOCKET\n");
return false;
}
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if(setsockopt(discoverSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)) == SOCKET_ERROR)
{
printf("setsockopt timeout failed\n");
close(discoverSocket);
return false;
}
socklen_t ttl = 2;
if(setsockopt(discoverSocket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == SOCKET_ERROR)
{
printf("setsockopt TTL failed\n");
close(discoverSocket);
return false;
}
if(setsockopt(discoverSocket, SOL_SOCKET, SO_BROADCAST, searchSatIPDevice, sizeof(searchSatIPDevice)) == SOCKET_ERROR)
{
printf("setsockopt broadcast failed\n");
close(discoverSocket);
return false;
}
upnpControl.sin_family = AF_INET;
upnpControl.sin_port = htons(0);
upnpControl.sin_addr.s_addr = INADDR_ANY;
if (bind(discoverSocket, (sockaddr*)&upnpControl, sizeof(upnpControl)) == SOCKET_ERROR)
{
printf("bind failed\n");
close(discoverSocket);
return false;
}
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_port = htons(1900);
broadcast_addr.sin_addr.s_addr = inet_addr("239.255.255.250");
for(int i = 0; i < 3; i++)
{
if(sendto(discoverSocket, searchSatIPDevice, strlen(searchSatIPDevice), 0, (sockaddr *)&broadcast_addr, sizeof(broadcast_addr)) == SOCKET_ERROR)
{
//printf("sendto failed\n");
close(discoverSocket);
return false;
}
else
{
usleep(10*100);
}
}
InitDiscoverThread();
return true;
}
void SatIP::ListenSSDPResponse()
{
while(1)
{
char buf[512];
memset(buf, 0, 512);
struct sockaddr_in broadcast_addr;
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_port = htons(1900);
broadcast_addr.sin_addr.s_addr = inet_addr("239.255.255.250");
int bcLen = sizeof(broadcast_addr);
//bool bRet = false;
while (recvfrom(discoverSocket, buf, 512, 0, (struct sockaddr*)&broadcast_addr, (socklen_t*)&bcLen) > 0)
{
printf("buf:%s\n",buf);
SATIP_SERVER_DESCRIPTION stServerDesc;
ostringstream ss;
if(strstr(buf, "device:SatIPServer"))
{
int i = 0;
char *deviceIp = strstr(buf, "LOCATION:") + 9; // get xml location including server description
while(deviceIp[i] == ' ') i++; // remove spaces from string
while(!isspace(deviceIp[i]))
{
ss << deviceIp[i];
++i;
}
stServerDesc.location = ss.str().c_str();
printf("location:%s\n",stServerDesc.location.c_str());
ss.str(""); // clear ss
i=0; // clear counter
deviceIp = strstr(buf, "http://") + 7; // get ip address
while(deviceIp[i] != ':')
{
ss << deviceIp[i];
++i;
}
stServerDesc.ipAddr = ss.str().c_str();
printf("ipAddr:%s\n", stServerDesc.ipAddr.c_str());
DownloadDeviceDescription(&stServerDesc);
stServerDesc.macAddr = GetMACAddressviaIP(stServerDesc.ipAddr);
printf("macAddr:%s\n", stServerDesc.macAddr.c_str());
if(IsServerProperToAdd(&stServerDesc))
vSatIPServers.push_back(stServerDesc);
printf("\n");
//bRet = true;
}
memset(buf, 0, 512);
}
}
}
How can I fix this issue? Any help would be appreciated.
Listening SSDP notify message is not related to sending M-SEARCH message. Devices like Sat>IP send NOTIFY message to 239.255.255.250 periodically even if you don't send M-SEARCH message. So, you should join a multicast group and receives from the group.
You can use the listener program in the following link by changing HELLO_PORT as 1900 and HELLO_GROUP as "239.255.255.250".
http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html
/*
* listener.c -- joins a multicast group and echoes all data it receives from
* the group to its stdout...
*
* Antony Courtney, 25/11/94
* Modified by: Frédéric Bastien (25/03/04)
* to compile without warning and work correctly
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define HELLO_PORT 1900
#define HELLO_GROUP "239.255.255.250"
#define MSGBUFSIZE 256
main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
u_int yes=1; /*** MODIFICATION TO ORIGINAL */
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
/**** MODIFICATION TO ORIGINAL */
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
/*** END OF MODIFICATION TO ORIGINAL */
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY); /* N.B.: differs from sender */
addr.sin_port=htons(HELLO_PORT);
/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}
/* now just enter a read-print loop */
while (1) {
addrlen=sizeof(addr);
if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,
(struct sockaddr *) &addr,&addrlen)) < 0) {
perror("recvfrom");
exit(1);
}
puts(msgbuf);
}
}
I use libevent-2.1.4-alpha, server can't receive connection event when initialized with IOCP enabled.
int main(int argc, char **argv)
{
struct event_config *evcfg;
struct event_base *base;
struct evconnlistener *listener;
struct sockaddr_in sin;
WSADATA wsa_data;
WSAStartup(0x0201, &wsa_data);
evcfg = event_config_new();
event_config_set_flag(evcfg, EVENT_BASE_FLAG_STARTUP_IOCP);
base = event_base_new_with_config(evcfg);
//base = event_base_new();
if (!base) {
fprintf(stderr, "Could not initialize libevent!\n");
return 1;
}
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
listener = evconnlistener_new_bind(base, listener_cb, (void *)base,
LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_FREE, -1,
(struct sockaddr*)&sin,
sizeof(sin));
if (!listener) {
fprintf(stderr, "Could not create a listener!\n");
return 1;
}
event_base_dispatch(base);
return 0;
}
I have searched all around the network, but no solution works!
#include "event2/thread.h"
event_config* pConfig = event_config_new();
event_config_set_flag( pConfig, EVENT_BASE_FLAG_STARTUP_IOCP );
evthread_use_windows_threads();
m_pBase = event_base_new_with_config( pConfig );
must call evthread_use_windows_threads() before event_base_new_with_config().