gpt4 book ai didi

C Windows 多线程 TCPIP 之间的连接

转载 作者:行者123 更新时间:2023-11-30 18:27:23 25 4
gpt4 key购买 nike

希望我能解释一下。我是 C 编程新手,尝试使用 TCPIP 发送和接收二进制文件。当客户端发送时,服务器应该一次接收多个文件。我创建了一个bat文件用于发送到服务器。如果文件是 2 或 3 个,则没有问题,但在尝试发送大约 5 个文件时有时会显示错误。实际上文件没有正确接收。我用过

multithreading Synchronization of Semaphore method

打印时接收端(服务器)结果如下:

file name (5000.dat)
Invalid argumen(5000.dat)
completetfile name (5120.dat)
(5120.dat) complete
file name (8192.dat)
(8192.dat) complete
file name (10240.dat)
(10240.dat) complete

上面有些文字错误,每次显示的结果都不一样。有时可以正常接收和写入文件,有时有些文件无法读取。

我的接收方代码如下:

#include <stdio.h>
#include <winsock2.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <process.h>
#include <windows.h>
void fileReceive(void *param);
HANDLE semaphore;
HANDLE threadHandle;
int main(int argc, char *argv[]){
if (argc > 1) {
goto l_param_error;
}
WSADATA wsaData; // Contains information about the Windows Sockets implementation
SOCKET sock0; // creates a socket that is bound to a specific transport service provider.
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
SOCKET sock; // creates a socket that is bound to a specific transport service provider

// Initiates use of the Winsock DLL by a process.
int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (error != 0) {
goto l_WSAIni_error;
}
addr.sin_family = AF_INET;// internetwork: UDP, TCP, etc.
addr.sin_port = htons(8080);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
sock0 = socket(AF_INET, SOCK_STREAM, 0);
if (sock0 == INVALID_SOCKET) {
goto l_socket_error;
}
// associates a local address with a socket
if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
goto l_bind_error;
}

while (1) {

// places a socket in a state in which it is listening for an incoming connection
if (listen(sock0, 1) != 0) {
goto l_socket_conn_setup_error;
}

len = sizeof(client);
// The accept function permits an incoming connection attempt on a socket.
sock = accept(sock0, (struct sockaddr *)&client, &len);
if (sock == INVALID_SOCKET) {
goto l_error_accpet;
}
semaphore = CreateSemaphore(0, 1, 1, 0);

threadHandle = (HANDLE)_beginthread(&fileReceive, 0, &sock);
if (threadHandle == 0) {
printf("Thread handle error");
return 1;
}
CloseHandle(semaphore);
}

WSACleanup();
return 0;
}

void fileReceive(void *param) {
int n = 0;
int sock = *((int *)param);
unsigned char buf[1];
unsigned char buff[256] = { 0 };
FILE *fp = NULL;
memset(buff, 0, sizeof(buff));
WaitForSingleObject(semaphore, INFINITE);
// Receive file name
int recvFile = recv(sock, buff, 255, 0);
ReleaseSemaphore(semaphore, 1, 0);
if ((recvFile == 0) || (recvFile == -1)) {
goto l_recv_error;
}
fp = fopen(buff, "wb+");
if (fp != NULL) {

printf("file name (%s)\n", buff);

while (n = recv(sock, &buf[0], 1, 0) > 0) {

size_t written = fwrite(&buf, sizeof(buf), 1, fp);

if (written != 1) {
goto l_write_error;
}
}
printf("(%s) complete\n", buff);

}
else {
goto l_fp_error;
}

fclose(fp);
closesocket(sock);
_endthread();
CloseHandle(threadHandle);
}

最佳答案

不幸的是,您有一长串问题。说白了,好像你不懂TCP(它是字节流协议(protocol)),也好像你不明白线程同步解决什么问题,怎么使用。鉴于此,您正在尝试一项远远超出您能力的任务,应该首先尝试更简单的任务。从不使用线程的 TCP 代码或不使用 TCP 的线程代码开始,这样您就不必立即把所有事情都做好。

以下是一些问题:

  1. 您将 &sock 传递给线程。但随后可能会在线程读取之前更改 sock 的值。

  2. 您在 TCP 连接上调用 recv 来获取文件名,并假设您将读取所有且仅读取文件名。 TCP 无法将字节“粘合”在一起形成消息。如果您想要发送和接收消息,您必须定义一个消息协议(protocol)并在 TCP 之上实现它。

  3. 你的信号量实际上并没有做任何事情。您不使用它来通信或同步任何内容。

  4. 每读取 1 个字节,就写入 256 个字节。

关于C Windows 多线程 TCPIP 之间的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56748160/

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