我正在尝试了解大学考试的C socket编程。 我做了这个简单的例子:
socket_server.c
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SA struct sockaddr
#define MAX_MESS_LEN 16
int main(){
struct sockaddr_in my_addr, cl_addr;
int ret, len, sk, cn_sk;
char cl_ip[INET_ADDRSTRLEN + 1], msg[MAX_MESS_LEN + 1];
sk = socket(AF_INET, SOCK_STREAM, 0); //creo socket TCP/IPv4 listener
printf("socket created! :)\n");
memset(&my_addr, 0, sizeof(my_addr)); //azzero struttura my_addr
my_addr.sin_family = AF_INET; //famiglia protocolli IPv4
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //in ascolto su qualsiasi interfaccia
my_addr.sin_port = htons(1234); //porta del socket
ret = bind(sk, (SA *) &my_addr, sizeof(my_addr)); //lego il socket alla struttura indirizzo
printf("socket binded! :)\n");
ret = listen(sk, 10); //mi pongo in ascolto sul socket con massimo 10 richieste pendenti
printf("socket listening (on any interface with port 1234)! :)\n");
len = sizeof(cl_addr);
printf("socket is going to wait for a request... zzzzZZZ\n");
cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista
printf("socket accepted request! :D\n");
inet_ntop(AF_INET, &cl_addr.sin_addr, cl_ip, INET_ADDRSTRLEN); //converto indirizzo IPv4 cl_addr.sin_addr in stringa (cl_ip)
printf("IP client: %s\n", cl_ip);
ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //attendo la ricezione di tutti i caratteri della stringa inviata sul socket dal client
msg[MAX_MESS_LEN + 1] = '\0';
printf("received data (%d bytes): %s\n", ret, msg);
if(ret == -1 || ret < MAX_MESS_LEN)
printf("recv ERROR! :(\n");
close(sk); //chiudo il server
}
socket_client.c
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#define SA struct sockaddr
#define MSG_LEN 17
int main(){
struct sockaddr_in srv_addr;
int ret, sk;
char msg[MSG_LEN];
sk = socket(AF_INET, SOCK_STREAM, 0);
printf("Socket created! :)\n");
memset(&srv_addr, 0, sizeof(srv_addr));
srv_addr.sin_family = AF_INET;
srv_addr.sin_port = htons(1234);
ret = inet_pton(AF_INET, "192.168.1.132", &srv_addr.sin_addr);
printf("Trying to establish a connection with 192.168.1.132 on port 1234...");
ret = connect(sk, (SA *) &srv_addr, sizeof(srv_addr)); //faccio una richiesta sul socket
if(ret != -1) printf("Connection established! :D\n");
else printf(" connection error :(\n");
strcpy(msg, "something to send"); //scrivo messaggio in una stringa
printf("sending message: %s\n", msg);
ret = send(sk, (void *) msg, strlen(msg), 0); //invio il messaggio sul socket
if(ret == -1 || ret < strlen(msg))
printf("send ERROR! :(\n");
close(sk);
}
用以下内容编译:
gcc socket_client.c -o socket_client
gcc socket_server.c -o socket_server
也许这是一个愚蠢的问题,但服务器中的recv函数总是失败,有一个示例输出:
服务器:
socket created! :)
socket binded! :)
socket listening (on any interface with port 1234)! :)
socket is going to wait for a request... zzzzZZZ
socket accepted request! :D
IP client: 192.168.1.132
received data (-1 bytes): ����
recv ERROR! :(
客户端:
Socket created! :)
Trying to establish a connection with 192.168.1.132 on port 1234...Connection established! :D
sending message: something to send
有什么问题?我不明白! :(我一步一步地跟着,老师的指导。
我正在运行arch linux 64位;) 谢谢你的回复!
答案 0 :(得分:4)
cn_sk = accept(sk, (SA *) &cl_addr, &len); //creo il socket connected per la richiesta in cima alla lista
...
ret = recv(sk, (void *) msg, MAX_MESS_LEN, MSG_WAITALL); //at
您不必在连接的套接字recv
上cn_sk
到客户端,而是在侦听器套接字sk
上。如果您检查errno
,您可能会看到ENOTCONN
。