I have the following pipeline which works fine:
gst-launch-1.0 -v tcpclientsrc host=192.168.1.132 port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink
I want to write a C program to do the same thing.
I translated the previous pipeline to the following code, but the video does not start (HELP ME)
#include <gst/gst.h>
int main(int argc, char *argv[]) {
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
/* Initialize GStreamer */
gst_init (&argc, &argv);
GError *error = NULL;
GstElement *pipeline = gst_parse_launch("tcpserversrc name=src ! gdpdepay ! rtph264depay ! avdec_h264 !videoconvert ! autovideosink", &error);
if (!pipeline) {
g_print ("Parse error: %s\n", error->message);
exit (1);
}
GstElement *src = gst_bin_get_by_name(GST_BIN(pipeline), "src");
g_object_set(src, "host", "192.168.1.132","port",5000, NULL);
// Start playing
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (pipeline);
return -1;
}else {
g_printerr("ERROR PLAY\n");
}
// Wait until error or EOS
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
// Parse message
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
break;
default:
// We should not reach here because we only asked for ERRORs and EOS
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
// Free resources
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
I can't spot anything obvious. Have you tried running with GST_DEBUG="*:2" ./myapp to see if there are some warnings
gdppay/gdpdepay is not currently ported in the ios 1.2 libraries. I've read it should be included in the 1.3 - 1.4 release. I'm guessing that's the issue.
Related
My pipeline is like this
gst-launch-1.0 v4l2src ! videoconvert ! xvimagesink
and my code is like this
#include <gst/gst.h>
// easier to pass them as callbacks
typedef struct _CustomData{
GstElement *pipeline;
GstElement *source;
GstElement *convert;
GstElement *sink;
}CustomData;
// callback function
// here src is the v4l2src, newpad is gstpad that has just been added to src element. This is usually the pad to which we want to lnk
// data is the pointer we provided when attaching to the signal.
static void pad_added_handler(GstElement *src, GstPad *new_pad,CustomData *data)
{
GstPad *sink_pad = gst_element_get_static_pad(data->convert, "sink");
GstPadLinkReturn ret;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;
if(gst_pad_is_linked(sink_pad))
{
g_print("we are linked. igonring\n");
}
// check the new pad types
// we have previously created a piece of pipeline which deals with videoconvert linked with xvimagesink and we will nto be able to link it to a pad producing video.
//gst-pad_get_current_caps()- retrieves current capabilities of pad
new_pad_caps = gst_pad_get_current_caps(new_pad);
new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
new_pad_type = gst_structure_get_name(new_pad_struct);
if(!g_str_has_prefix(new_pad_type, "video/x-raw"))
{
g_print("It has new pad type");
}
// gst_pad_link tries to link two pads . the link must be specified from source to sink and both pads must be owned by elements residing in same pipeline
ret = gst_pad_link(new_pad, sink_pad);
if(GST_PAD_LINK_FAILED(ret))
{
g_print("type is new_pad_type");
}
if(new_pad_caps !=NULL)
{
gst_caps_unref(new_pad_caps);
}
gst_object_unref(sink_pad);
}
int main(int argc, char *argv[])
{
GMainLoop *loop;
CustomData data;
GstBus *bus;
GstMessage *msg;
gboolean terminate = FALSE;
gst_init(&argc, &argv);
// loop = g_main_loop_new(NULL, FALSE);
// create the elements
data.source = gst_element_factory_make("v4l2src", "source");
data.convert = gst_element_factory_make("videoconvert", "convert");
data.sink = gst_element_factory_make("xvimagesink", "sink");
data.pipeline = gst_pipeline_new("new-pipeline");
if(!data.pipeline || !data.source || !data.convert || !data.sink)
{
g_printerr("Not all elements could be created\n");
return -1;
}
//we did not link source at this point of time, we will do it later
gst_bin_add_many(GST_BIN(data.pipeline), data.source, data.convert, data.sink, NULL);
// we link convert element to sink, do not link them with source. we dont have source pads here. so we just have videoconvert->sink unlinked
// gst_element_link(data.source, data.convert);
if(!gst_element_link(data.convert,data.sink))
{
g_printerr("elements could not be linked\n");
gst_object_unref(data.pipeline);
return -1;
}
// we set the device source
//g_object_set(source, "device", "/dev/video0", NULL);
//connect to pad added signal.
// we want to attach pad added signal to source element. to do so, we are using g_signal_connect and provide callback function and datapointer.
// when source element has enough information to start producing data, it will create source pads and trigger the pad added signal. at this point, our callback is called
g_signal_connect(G_OBJECT(data.source), "pad-added", G_CALLBACK(pad_added_handler), &data );
//g_signal_connect(G_OBJECT(data.source), "pad-added", G_CALLBACK(handler), &data);
GstStateChangeReturn ret;
ret =gst_element_set_state (data.pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data.pipeline);
return -1;
}
// g_main_loop_run(loop);
/* Listen to the bus */
bus = gst_element_get_bus (data.pipeline);
do {
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
terminate = TRUE;
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
terminate = TRUE;
break;
case GST_MESSAGE_STATE_CHANGED:
/* We are only interested in state-changed messages from the pipeline */
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data.pipeline)) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
g_print ("Pipeline state changed from %s to %s:\n",
gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));
}
break;
default:
/* We should not reach here */
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
} while (!terminate);
/* Free resources */
gst_object_unref (bus);
gst_element_set_state(data.pipeline, GST_STATE_NULL);
gst_object_unref(data.pipeline);
return 0;
}
and I am getting error like this
Pipeline state changed from NULL to READY:
Pipeline state changed from READY to PAUSED:
Error received from element source: Internal data stream error.
Debugging information: gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:new-pipeline/GstV4l2Src:source:
streaming stopped, reason not-linked (-1)
Please let me know what changes should I make to make my pipeline work. Thanks! the above code is based on dynamic pipeline example from gstreamer tutorials. I dont understand where I am going wrong.
The following works though
#include <gst/gst.h>
int main(int argc, char *argv[])
{
GstElement *pipeline, *source,*filter, *convert, *sink;
GstBus *bus;
GstMessage *msg;
GstCaps *caps;
gst_init(&argc, &argv);
source = gst_element_factory_make("v4l2src", "source");
filter = gst_element_factory_make("capsfilter","filter");
convert = gst_element_factory_make("videoconvert", "convert");
sink = gst_element_factory_make("xvimagesink", "sink");\
pipeline = gst_pipeline_new("pipe");
gst_bin_add_many(GST_BIN(pipeline), source, convert,sink, NULL);
gst_element_link_many(source,convert,sink,NULL);
caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "YUY2", NULL);
g_object_set(G_OBJECT(filter), "caps", caps, NULL);
gst_element_set_state(pipeline,GST_STATE_PLAYING);
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
break;
default:
/* We should not reach here because we only asked for ERRORs and EOS */
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
/* Free resources */
gst_object_unref(bus);
gst_element_set_state(pipeline,GST_STATE_NULL);
gst_object_unref(pipeline);
}
Any ideas why if I add pads, it is not working well??
I've spent hours trying to fix this:
I'm trying to use the ffmpeg api on iOS. My Xcode project is building and I can call ffmpeg api functions. I am trying to write code that decodes a video (Without outputting anything for now), and I keep getting error -35: "Resource temporarily unavailable".
The input file is from the camera roll (.mov) and I'm using Mpeg-4 for decoding. All I'm currently doing is getting data from the file, parsing it and sending the parsed packets to the decoder. When I try to get frames, all I get is an error. Does anyone know what I'm doing wrong?
+(void)test: (NSString*)filename outfile:(NSString*)outfilename {
/* register all the codecs */
avcodec_register_all();
AVCodec *codec;
AVCodecParserContext *parser;
AVCodecContext *c= NULL;
int frame_count;
FILE* f;
AVFrame* frame;
AVPacket* avpkt;
avpkt = av_packet_alloc();
//av_init_packet(avpkt);
char buf[1024];
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
uint8_t *data;
size_t data_size;
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
printf("Decode video file %s to %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding], [outfilename cStringUsingEncoding:NSUTF8StringEncoding]);
/* find the h264 video decoder */
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4);
if (!codec) {
fprintf(stderr, "Codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
if (!c) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* open it */
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "Could not open codec\n");
exit(1);
}
f = fopen([filename cStringUsingEncoding:NSUTF8StringEncoding], "rb");
if (!f) {
fprintf(stderr, "Could not open %s\n", [filename cStringUsingEncoding:NSUTF8StringEncoding]);
exit(1);
}
frame = av_frame_alloc();
if (!frame) {
fprintf(stderr, "Could not allocate video frame\n");
exit(1);
}
frame_count = 0;
parser = av_parser_init(codec->id);
if (!parser) {
fprintf(stderr, "parser not found\n");
exit(1);
}
while (!feof(f)) {
/* read raw data from the input file */
data_size = fread(inbuf, 1, INBUF_SIZE, f);
if (!data_size)
break;
/* use the parser to split the data into frames */
data = inbuf;
while (data_size > 0) {
int ret = av_parser_parse2(parser, c, &avpkt->data, &avpkt->size, data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (ret < 0) {
fprintf(stderr, "Error while parsing\n");
exit(1);
}
data += ret;
data_size -= ret;
if (avpkt->size){
char buf[1024];
ret = avcodec_send_packet(c, avpkt);
if (ret < 0) {
fprintf(stderr, "Error sending a packet for decoding\n");
continue;
exit(1);
}
while (ret >= 0) {
ret = avcodec_receive_frame(c, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
char e [1024];
av_strerror(ret, e, 1024);
fprintf(stderr, "Fail: %s !\n", e);
// ~~~~~~~~ This is where my program exits ~~~~~~~~~~~~~~~~~~~~~~~~~~~
return;
}
else if (ret < 0) {
fprintf(stderr, "Error during decoding\n");
exit(1);
}
}
}
}
}
/* some codecs, such as MPEG, transmit the I and P frame with a
latency of one frame. You must do the following to have a
chance to get the last frame of the video */
fclose(f);
avcodec_close(c);
av_free(c);
av_frame_free(&frame);
printf("\n");
}
AVERROR(EAGAIN) is not an error, it just means output is not yet available and you need to call _send_packet() a few more times before the first output will be available from _receive_frame().
The output is buffered (delayed) to allow for B-frames and frame threading.
I have ran this code many times trying to figure out why it doesn't work. I am getting the feed from a IP camera. The program goes through each but then it fails to play. The original start out was gst-launch-1.0 udpsrc address=[ip] port=[port] ! application/x-rtp,clock-rate=10,media=video ! rtpmp4vdepay ! decodebin ! d3dvideosink
I used gst_parse_launch() with it and works but for some reason won't play. I have been trying figure out what I am doing wrong.
convertString.h just throws the Char *port to a method to convert string to int.I don't want to use the gst_parse_launch() because I am wanting to use it to overlay into application.
Anybody have any idea what I am missing?
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <stdio.h>
#include <string.h>
#include "convertString.h"
#include <Windows.h>
#include <direct.h>
void nullvalues(GstElement*,GstBus*,GstMessage*);
int main(int argc, char *argv[])
{
GstElement *pipeline,*sink,*source, *rtppay,*filter1,*decodebin;
GstCaps *filtercaps;
GstBus *bus;
GstMessage *msg;
gboolean link_ok = FALSE;
GstStateChangeReturn ret;
char *ip_address = [ip];
char *port = [port];
char *window_handle = "";
char *title = "";
int wid;
char *sourcestring = "";
#define url_size 28
char url[url_size];
strcpy_s(url,url_size,"");
while ((argc > 1) && (argv[1][0] == '-'))
{
switch (argv[1][1])
{
case 'i':
ip_address = &argv[1][2];
break;
case 'p':
port = &argv[1][2];
break;
case 'w':
window_handle = &argv[1][2];
break;
case 't':
title = &argv[1][2];
break;
}
++argv;
--argc;
}
strcat_s(url,url_size,"udp://");
strcat_s(url,url_size,ip_address);
strcat_s(url,url_size,":");
strcat_s(url,url_size,port);
/* Initialize GStreamer */
gst_init(&argc,&argv);
/* Build Pipeline */
if(title != "")
pipeline = gst_pipeline_new (title);
else
pipeline = gst_pipeline_new("My pipeline");
source = gst_element_factory_make ("udpsrc","source");
filter1 = gst_element_factory_make("capsfilter","filter");
rtppay = gst_element_factory_make( "rtpmp4vdepay", "depayl");
decodebin = gst_element_factory_make ("decodebin","decode");
sink = gst_element_factory_make ("d3dvideosink", "sink");
gst_bin_add_many (GST_BIN (pipeline),source,filter1,rtppay,decodebin,sink, NULL);
filtercaps = gst_caps_new_simple("application/x-rtp","clock-rate",G_TYPE_INT,10,"media",G_TYPE_STRING,"video",NULL);
g_object_set(GST_OBJECT(source),"address",ip_address,NULL);
g_object_set(GST_OBJECT(source),"port",StringToInt(port),NULL);
g_object_set (G_OBJECT (filter1), "caps",filtercaps,NULL);
gst_caps_unref(filtercaps);
link_ok = gst_element_link_many(source,filter1,rtppay,decodebin,sink);
if(!link_ok)
printf("%s\nNOPE\n");
/* Start playing */
ret = gst_element_set_state (pipeline, GST_STATE_READY);
if(ret == GST_STATE_CHANGE_FAILURE)
printf("\nFailed\n");
else if(ret == GST_STATE_CHANGE_SUCCESS)
printf("\nSuccess\n");
/* Wait until error or EOS */
bus = gst_element_get_bus (pipeline);
msg = gst_bus_timed_pop_filtered(bus,GST_CLOCK_TIME_NONE,GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* Free resources */
if (msg != NULL)
gst_message_unref (msg);
gst_object_unref (bus);
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (pipeline);
printf("\nDone\n");
return 0;
}
If gst_parse_launch() is working for you I suggest to use it. You can still overlay the d3dvideosink in your application.
Just use a unique name for the d3dvideosink element in the pipeline definition (e.g. "d3dvideosink name=myvideosink").
Get a handle to the d3dvideosink from the pipeline via gst_bin_get_by_name(). This handle should then also support the GstVideoOverlay interface and you can set the overlay via gst_video_overlay_set_window_handle().
using this will solve the problem
Gstreamer Decodebin
How can I capture 802.11 beacon frames on my linux machine using a C program.Also how can I send a frame response using a C program?
Try using libpcap. See this answer on SO for a basic example.
below program only work :-
1. if your device support link layer type as DLT_IEEE802_11_RADIO
2. if you ahev libpacp installed in your machine.
3. compile it with libcap library( ex:- cc prog.c -lpcap
4. during run provide interface on command line ( ex:- a.out wlan0)
#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void packet_view(unsigned char *args,const struct pcap_pkthdr *h,const unsigned char *p);
#define SNAP_LEN 3000
void packet_view(
unsigned char *args,
const struct pcap_pkthdr *h,
const unsigned char *p
){
int len;
len = 0;
printf("PACKET\n");
while(len < h->len) {
printf("%02x ", *(p++));
if(!(++len % 16))
printf("\n");
}
printf("\n");
return ;
}
int main(int argc, char **argv)
{
char *dev = NULL; /* capture device name */
char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */
pcap_t *handle; /* packet capture handle */
char filter_exp[] = "wlan type mgt subtype beacon"; /* filter expression [3] */
// char filter_exp[] = "ip"; /* filter expression [3] */
struct bpf_program fp; /* compiled filter program (expression) */
bpf_u_int32 mask; /* subnet mask */
bpf_u_int32 net; /* ip */
int num_packets = 10; /* number of packets to capture */
/* check for capture device name on command-line */
if (argc == 2) {
dev = argv[1];
}
else if (argc > 2) {
fprintf(stderr, "error: unrecognized command-line options\n\n");
exit(EXIT_FAILURE);
}
else {
/* find a capture device if not specified on command-line */
dev = pcap_lookupdev(errbuf);
if (dev == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n",
errbuf);
exit(EXIT_FAILURE);
}
}
/* get network number and mask associated with capture device */
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n",
dev, errbuf);
net = 0;
mask = 0;
}
/* print capture info */
printf("Device: %s\n", dev);
printf("Number of packets: %d\n", num_packets);
printf("Filter expression: %s\n", filter_exp);
/* open capture device */
handle = pcap_open_live(dev, SNAP_LEN, 1, -1, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
/* for Ethernet device change the type to DLT_EN10MB */
/* your wlan device need to supprot this link layer type otherwise failure */
if (pcap_datalink(handle) != DLT_IEEE802_11_RADIO) {
fprintf(stderr, "%s is not an Wlan packet\n", dev);
exit(EXIT_FAILURE);
}
/* compile the filter expression */
if (pcap_compile(handle, &fp, filter_exp, 1,PCAP_NETMASK_UNKNOWN) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
/* apply the compiled filter */
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
/* now we can set our callback function */
pcap_loop(handle, num_packets, packet_view, NULL);
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
printf("\nCapture complete.\n");
return 0;
}
Hello fine community at stackoverflow! I've been lurking around using the site for about a year now, and just have come to the need to post a question.
I'm a bit of a klutz when it comes to coding, so go easy on me.
Here's the code (most of it is the sample winsock MSDN code :P):
Client:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
void clarify(char *recvdata);
char mdata[7];
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "10150"
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("173.21.56.58", DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
char sendbuf[512];
std::cin.getline(sendbuf, 512);
iResult = send( ConnectSocket, sendbuf, 512, 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
std::cout<<"sendbuf: "<<sendbuf<<"\n";
std::cout<<"strlen(sendbuf): "<<strlen(sendbuf)<<"\n";
printf("Bytes Sent: %ld\n", iResult);
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
std::cout<<"recvbuf: "<<recvbuf<<"\n";
std::cout<<"recvbuflen: "<<recvbuflen<<"\n";
std::cout<<"strlen(recvbuf): "<<strlen(recvbuf)<<"\n";
std::cout<<recvbuf[0]<<"\n";
std::cout<<recvbuf[1]<<"\n";
std::cout<<recvbuf[2]<<"\n";
std::cout<<recvbuf[3]<<"\n";
std::cout<<recvbuf[4]<<"\n";
std::cout<<recvbuf[5]<<"\n";
std::cout<<recvbuf[6]<<"\n";
std::cout<<recvbuf[7]<<"\n";
std::cout<<recvbuf[8]<<"\n";
std::cout<<recvbuf[9]<<"\n";
std::cout<<recvbuf[10]<<"\n";
std::cout<<recvbuf[11]<<"\n";
std::cout<<recvbuf[12]<<"\n";
clarify(recvbuf);
std::cout<<"mdata(main()): "<<mdata<<"\n";
if (mdata == "anarchy") {std::cout<<"This is Anarchy. :)";}
else {std::cout<<"Nope. :( ";}
} while( iResult > 0 );
std::cin.ignore();
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
void clarify(char *recvdata)
{
std::cout<<"recvdata: "<<recvdata<<"\n";
for (int i=0; i<(strlen(recvdata)); i++) {
mdata[i]=recvdata[i];
std::cout<<mdata[i]<<"\n";
}
std::cout<<"mdata(clarify()): "<<mdata<<"\n";
}
And the server code is the sample MSDN winsock code.
I realize the code has a bunch of sloppy extras added in, but rest assured, those are for my own thoughts and reminders. So, please don't bother telling me other places I could clean up. I'll take care of that when I get closer to finishing my project (a long way away :) ).
So, I'm having issues comparing the "mdata" variable with the characters "anarchy".
Even when I send "anarchy" through winsock, it comes back as "anarchy", and I run it through "clarify()" just for good measure, it still doesn't seem to equal "anarchy".
I'm sure it's a noob mistake I'm making here, so please go easy on me...
EDIT:
Here's the output after typing "anarchy" for the "sendbuf" input:
anarchy
sendbuf: anarchy
strlen(sendbuf): 7
bytes sent: 512
bytes recieved: 512
recvbuf: anarchy
recvbuflen: 512
strlen(recvbuf): 7
a
n
a
r
c
h
y
f
4
i
w
,
recvdata: anarchy
a
n
a
r
c
h
y
mdata(clarify()): anarchy
mdata(main()): anarchy
Nope :(
You're comparing the address of a c-string literal to the address stored in mdata.
if (mdata == "anarchy") {std::cout<<"This is Anarchy. :)";}
"anarchy" is a string literal, and has an address. You're comparing that arbitrary address with the address stored in the mdata variable. They're not the same addresses, so the equality check fails.
You don't mean to compare the addresses of where your two strings are stored, you mean to compare the characters stored at those strings.
strncmp is your friend here.