Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy sending datagram doesn't work if I don't create a TCP connection first?
    text
    copied!<p>The following c++ program should convert each line to uppercase using socket datagram to communicate between two threads.</p> <pre><code>Example: Hello World!&lt;return&gt; HELLO WORLD! 123abc!&lt;return&gt; 123ABC! &lt;return&gt; &lt;end program&gt; </code></pre> <p>The program as written works for me, however if I comment the <code>bugfix()</code> function call in the main the program wait indefinitely after the first line of input.</p> <pre><code>Example: Hello World!&lt;return&gt; &lt;the program wait indefinitely&gt; </code></pre> <p>This happen on windows 7 with the last update as 10/04/2011 using the last MinGW32.</p> <pre><code>#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;cctype&gt; #include &lt;sys/types.h&gt; #include &lt;winsock.h&gt; #include &lt;windows.h&gt; #include &lt;process.h&gt; using namespace std; #define CHECK(exp, cond) do { typeof(exp) _check_value_ = exp; check(_check_value_ cond, _check_value_, __LINE__, #exp #cond); } while(0) template &lt;class T&gt; void check(bool ok, T value, int line, const char* text) { if (!ok) { cerr &lt;&lt; "ERROR(" &lt;&lt; line &lt;&lt; "):" &lt;&lt; text &lt;&lt; "\nReturned: " &lt;&lt; value &lt;&lt; endl; cerr &lt;&lt; "errno=" &lt;&lt; errno &lt;&lt; endl; cerr &lt;&lt; "WSAGetLastError()=" &lt;&lt; WSAGetLastError() &lt;&lt; endl; exit(EXIT_FAILURE); } } #define DATA_CAPACITY 1000 #define PORT 23584 #define TEST_IP "192.0.32.10" #define MYSELF "127.0.0.1" #define DST_IP MYSELF sockaddr_in address(u_long ip, u_short port) { sockaddr_in addr = { }; addr.sin_family = AF_INET; addr.sin_port = port; addr.sin_addr.s_addr = ip; return addr; } void __cdecl client_thread(void* args) { SOCKET s = *(SOCKET*)args; sockaddr_in addr = address(inet_addr(DST_IP), htons(PORT)); char data[DATA_CAPACITY]; while (1) { cin.getline(data, DATA_CAPACITY); int data_len = strlen(data); CHECK(sendto(s, data, data_len, 0, (sockaddr*)&amp;addr, sizeof addr), &gt;= 0); CHECK(recvfrom(s, data, DATA_CAPACITY, 0, NULL, NULL), &gt;= 0); cout &lt;&lt; data &lt;&lt; endl; if (data_len == 0) break; } CHECK(closesocket(s), == 0); } void __cdecl server_thread(void* args) { SOCKET s = *(SOCKET*)args; sockaddr_in addr = address(INADDR_ANY, htons(PORT)); int addr_size = sizeof addr; CHECK(bind(s, (sockaddr*)&amp;addr, sizeof addr), != SOCKET_ERROR); char data[DATA_CAPACITY]; while (1) { int data_len = recvfrom(s, data, DATA_CAPACITY, 0, (sockaddr*)&amp;addr, &amp;addr_size); CHECK(data_len, &gt;= 0); for (int i = 0; i &lt; data_len; i++) if (islower(data[i])) data[i] = toupper(data[i]); CHECK(sendto(s, data, data_len, 0, (sockaddr*)&amp;addr, addr_size), &gt;= 0); if (data_len == 0) break; } CHECK(closesocket(s), == 0); } // This function create a TCP connection with www.example.com and the close it void bugfix() { SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in addr = address(inet_addr(TEST_IP), htons(80)); connect(s, (sockaddr*)&amp;addr, sizeof addr); CHECK(closesocket(s), == 0); } int main() { cout &lt;&lt; "Convert text to uppercase, an empty line terminate the program" &lt;&lt; endl; WSADATA wsaData; CHECK(WSAStartup(MAKEWORD(2, 2), &amp;wsaData), == 0); SOCKET client = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); SOCKET server = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); CHECK(client, != INVALID_SOCKET); CHECK(server, != INVALID_SOCKET); // if this function is not called the program doesn't work bugfix(); HANDLE hClient = (HANDLE)_beginthread(client_thread, 0, &amp;client); HANDLE hServer = (HANDLE)_beginthread(server_thread, 0, &amp;server); HANDLE h[] = { hClient, hServer }; WaitForMultipleObjects(sizeof h / sizeof *h, h, TRUE, INFINITE); CHECK(WSACleanup(), == 0); return EXIT_SUCCESS; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload