Re: GIO - Simple socket Client - Need suggestions on which API set to use (or sample code)
- From: "Thomas A. Moulton" <tom moulton us>
- To: gtk-app-devel-list gnome org
- Subject: Re: GIO - Simple socket Client - Need suggestions on which API set to use (or sample code)
- Date: Sat, 25 May 2013 08:51:27 -0400
Well I think from the archives I saw mention of GIOChannel, so gave it a
try.
case CONNECT:
sock = socket_connect(host, 4321);
if (sock < 0) {
fcm->State = OFFLINE;
break;
}
fcm->iochannel = g_io_channel_unix_new (sock);
g_io_channel_set_encoding(fcm->iochannel, NULL, &error);
g_io_channel_set_buffered(fcm->iochannel, FALSE);
fcm->State = CONNECTED;
fcm->sid = g_io_add_watch(fcm->iochannel, (G_IO_IN |
G_IO_ERR | G_IO_HUP), fibs_callback, (gpointer)fcm);
break;
case BOT_CON_ERROR:
g_io_channel_unref(fcm->iochannel);
g_io_channel_shutdown(fcm->iochannel, FALSE, NULL);
fcm->iochannel = NULL;
break;
and my callback is:
gboolean fibs_callback( GIOChannel *ioch, GIOCondition condition,
gpointer data)
{
FCM *fcm = (FCM *)data;
char message[MAXBUF];
gsize l, len, need;
GIOStatus status;
GError *error=NULL;
printf("callback: %d\r\n", condition);fflush(stdout);
// (G_IO_IN | G_IO_ERR | G_IO_HUP)
if ((condition & G_IO_HUP) || (condition & G_IO_ERR)) {
fcm->State = CON_ERROR;
return FALSE;
}
if (condition & G_IO_IN) {
// Received Data
len = strlen(fcm->buffer);
need = MAXBUF - len;
//printf("reading: len %d need %d buff: %s\r\n", len, need,
fcm->buffer);fflush(stdout);
status = g_io_channel_read_chars(fcm->iochannel,
fcm->buffer+len, need, &l, &error);
if (status != G_IO_STATUS_NORMAL) {
printf("Bad Read Errno %d\n", (int)status);fflush(stdout);
fcm->State = CON_ERROR;
return 0;
} /* Process data */
//printf("read %d buff is: %s\r\n", l, fcm->buffer);fflush(stdout);
[snip]
}
}
return TRUE;
}
I did find that I needed to turn off buffering with
g_io_channel_set_buffered(fcm->iochannel, FALSE);
Maybe because not all my data is complete lines (like a login prompt)
I hope this helps someone.
Tom
ps. here is my socket_connect function, pretty standard code
int socket_connect(char *host, int port)
{
struct sockaddr_in serv_addr;
static struct hostent *server;
static char last_host[256];
int servfd;
char **p;
if(last_host[0] || strcasecmp(last_host, host)!=0) {
if(!(server = gethostbyname(host))) {
printf("failed to look up server (%s)\n%d: %strerrors",
host, h_errno, strerror(h_errno));
return -1;
}
strncpy(last_host, host, 255);
}
if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("Socket create error (%d): %s", errno, strerror(errno));
return -1;
}
printf("connecting to %s:%d", host, port);
for (p = server->h_addr_list; *p; p++) {
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length);
serv_addr.sin_port = htons(port);
printf("trying %s", inet_ntoa(serv_addr.sin_addr));
if(connect(servfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) == -1) {
if(errno!=ECONNREFUSED && errno!=ETIMEDOUT &&
errno!=ENETUNREACH) {
break;
}
} else {
printf("connected\n");
return servfd;
}
}
printf("Could not connect to %s:%d\n%d:%s", host, port, errno,
strerror(errno));
close(servfd);
return -1;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]